Python 3.x 将一个int64拆分为两个int32,执行数学运算,然后重新合并
我在64位整数限制的硬件约束下工作。不支持浮点。我处理的是非常大的整数,需要进行乘除运算。乘法时,我遇到64位溢出。我正在用python制作一个解决方案的原型。这就是我的职能: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
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);