假设我想计算以下内容:
A/Z
其中A
长度为128位,Z
长度为64位。 A
存储在2个64位寄存器中,因为系统寄存器最多可存储64位。什么是计算结果的有效方法?
P.S:我通过使用CSD表示解决了类似的乘法问题。但是,这需要先计算1/Z
。
答案 0 :(得分:0)
我假设你想要整数除法,所以这里是数学:
A = { a0 + (a1<<64) }
D = { d0 + (d1<<64) } ... division result
Z = { z0 }
D = A/Z
D = (a0 + (a1<<64))/z0
D = (a0/z0) + ((a1<<64)/z0)
D = (a0/z0) + ((a1/z0)<<64) + (((a1%z0)<<64)/z0)
d0 = (a0/z0) + (((a1%z0)<<64)/z0)
d1 = a1/z1 + d0>>64
d0&=0xFFFFFFFFFFFFFFFF
和一些'C ++'代码:
ALU32 alu;
DWORD a1=0x12345678,a0=0x9ABCDEF0,d0,d1,z0=0x23,i;
// D = 0085270A C297AE99 R = 5
if (z0>=2)
{
d1=a1/z0; d0=a0/z0;
a1=a1%z0; a0=a0%z0;
if (a1)
{
i= (0xFFFFFFFF/z0) *a1;
alu.add(d0,d0,i); // addition with carry
alu.adc(d1,d1,0);
i=((0xFFFFFFFF%z0)+1)*a1;
a0+=i; i=a0/z0; a0%=z0;
alu.add(d0,d0,i); // addition with carry
alu.adc(d1,d1,0);
}
}
注意:
这只是32位。要将其转换为64位,只需将0xFFFFFFFF
更改为0xFFFFFFFFFFFFFFFF
,将DWORD更改为您的数据类型
ALU32只是我用于进行基本32位操作的类。我假设你在asm中这样做,所以你使用CPU携带。
分部结果位于d0
,d1
剩余结果位于a0
代码不处理负值并除以0
,1
。添加if
来处理它。
答案 1 :(得分:0)
解决此类问题的正确方法是回归基础:
Q
和其他R
R
的相同位数,并将结果添加到临时寄存器。double
,除以分母然后加到商中。