Python 3.x 将一个int64拆分为两个int32,执行数学运算,然后重新合并

Python 3.x 将一个int64拆分为两个int32,执行数学运算,然后重新合并,python-3.x,bit-manipulation,int64,Python 3.x,Bit Manipulation,Int64,我在64位整数限制的硬件约束下工作。不支持浮点。我处理的是非常大的整数,需要进行乘除运算。乘法时,我遇到64位溢出。我正在用python制作一个解决方案的原型。这就是我的职能: upper = x >> 32 #x is cast as int64 before being passed to this function lower = x & 0x00000000FFFFFFFF temp_upper = upper * y // z #Dividing first is

我在64位整数限制的硬件约束下工作。不支持浮点。我处理的是非常大的整数,需要进行乘除运算。乘法时,我遇到64位溢出。我正在用python制作一个解决方案的原型。这就是我的职能:

upper = x >> 32 #x is cast as int64 before being passed to this function
lower = x & 0x00000000FFFFFFFF

temp_upper = upper * y // z #Dividing first is not an option, as this is not the actual equation I am working with. This is just to make sure in my testing I overflow unless I do the splitting.
temp_lower = lower * y // z

return temp_upper << 32 | lower
upper=x>>32#x在传递到此函数之前被强制转换为int64
下限=x&0x00000000FFFFFFFF
temp_upper=upper*y//z#首先除以不是一个选项,因为这不是我正在处理的实际方程。这只是为了确保在我的测试中我溢出,除非我进行拆分。
温度较低=较低*y//z

返回temp\u upper据我所知,您希望执行
(x*y)//z

您的数字
x,y,z
都适合64位,但中间
x*y
需要128位

你的问题确实与分裂有关:你有

h * y = qh * z + rh
l * y = ql * z + rl

h * y << 32 + l*y = (qh<<32 + ql) * z + (rh<<32 + rl)

然后得到总商
qhI,我不太懂,也许我很笨,但是如果你有Python,你有任意大小的整数,没有64位的限制。因此,您可以只进行计算以获得结果,并将其打包到您想要的任何二进制结构中(您到底在使用什么接口?),我仍然不清楚您想要计算什么。是(x*y)/z表示128位x,而机器只能进行64位数学运算吗?y和z有多少位?变量是有符号的还是无符号的?@juanpa.arrivillaga python似乎只用于原型设计,OP不能使用大整数预构建算法。这也可能是语言不可知论。嘿,伙计们,澄清一下。python仅用于原型,代码作为机器代码在硬件上运行,64位是寄存器的大小。我需要能够对大于64位的数字进行数学运算。一种方法是(在我看来),分成上下两部分,然后在完成数学运算后重新组合。
rh<<32 + l * y = ql' * z + rl'
p = 1<<32;

function (a1,a0) = split(a)
    a1 = a >> 32;
    a0 = a - (a1 * p);

function (a2,a1,a0) = mul22(x,y)
    (x1,x0) = split(x) ;
    (y1,y0) = split(y) ;
    (h1,h0) = split(x1 * y1);
    assert(h1 == 0); -- assume that results fits on 96 bits
    (l1,l0) = split(x0 * y0);
    (m1,m0) = split((x1 - x0) * (y0 - y1));  -- karatsuba trick
    a0 = l0;
    (carry,a1) = split( l1 + l0 + h0 + m0 );
    a2 = l1 + m1 + h0 + carry;
    
function (q,r) = quorem(a,b)
    q = a // b;
    r = a - (b * q);

function (q1,q0,r0) = div21(a1,a0,b0)
   (q1,r1) = quorem(a1,b0);
   (q0,r0) = quorem( r1 * p + a0 , b0 );
   (q1,q0) = split( q1 * p + q0 );
   
function q = div32(a2,a1,a0,b1,b0)
    (q,r) = quorem(a2*p+a1,b1*p+b0);
    q = q * p;
    (a2,a1)=split(r);
    if a2<b1
        (q1,q0,r)=div21(a2,a1,b1);
        assert(q1==0); -- since a2<b1...
    else
        q0=p-1;
        r=(a2-b1)*p+a1+b1;
    (d1,d0) = split(q0*b0);
    r = (r-d1)*p + a0 - d0;
    while(r < 0)
        q = q - 1;
        r = r + b1*p + b0;
   
function t=muldiv(x,y,z)
    (a2,a1,a0) = mul22(x,y);
    (z1,z0) = split(z);
    if z1 == 0
        (q2,q1,r1)=div21(a2,a1,z0);
        assert(q2==0); -- otherwise result will not fit on 64 bits
        t = q1*p + ( ( r1*p + a0 )//z0);
    else
        t = div32(a2,a1,a0,z1,z0);