通过常量将存储在2个寄存器中的非常大的数字分开的有效方法

时间:2013-10-14 08:57:08

标签: algorithm bit-manipulation division

假设我想计算以下内容:

A/Z

其中A长度为128位,Z长度为64位。 A存储在2个64位寄存器中,因为系统寄存器最多可存储64位。什么是计算结果的有效方法?

P.S:我通过使用CSD表示解决了类似的乘法问题。但是,这需要先计算1/Z

2 个答案:

答案 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携带。
分部结果位于d0d1 剩余结果位于a0 代码不处理负值并除以01。添加if来处理它。

答案 1 :(得分:0)

解决此类问题的正确方法是回归基础:

  • 用分母划分最重要的寄存器
  • 计算商Q和其他R
  • 定义一个新的临时寄存器,最好与其他2
  • 相同的长度
  • 其余应占用临时寄存器中最重要的位
  • 将较低有效寄存器向右移动包含i R的相同位数,并将结果添加到临时寄存器。
  • 返回第1步
分割后,得到的休息必须转换为double,除以分母然后加到商中。