请计算实现整数运算 a*b/c, (a,b,c都是非常大的32位整数)
思路:用32位来模拟64位的加减乘除,可能是一个能够保证计算精度的好方法。
请老师指点,如何实现?
9 个解决方案
#1
能内嵌汇编不能?
#2
想办法手工处理一个进位和借位就是了。
#3
考虑用数组 看行不
#4
直接在网上找大数运算之类的类 吧。
#5
大数运算,支持任意长度的 + - * / %
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx
#6
我看到了一段代码挺好的,能实现 a*b/c的功能,
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下
// 计算(u*v)%m
unsigned mul_mod(unsigned u, unsigned v, unsigned z)
{
// 如果u*v没有溢出, 则直接计算
if((u*v)/u == v) return (u*v)%z;
// 进行长乘法(结果为64位)
unsigned u0, v0, w0;
unsigned u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u > > 16;
v0 = v & 0xFFFF; v1 = v > > 16;
w0 = u0*v0;
t = u1*v0 + (w0 > > 16);
w1 = t & 0xFFFF;
w2 = t > > 16;
w1 = u0*v1 + w1;
// x为高32位, y为低32位
unsigned x = u1*v1 + w2 + (w1 > > 16);
unsigned y = u*v;
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
}
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下
// 计算(u*v)%m
unsigned mul_mod(unsigned u, unsigned v, unsigned z)
{
// 如果u*v没有溢出, 则直接计算
if((u*v)/u == v) return (u*v)%z;
// 进行长乘法(结果为64位)
unsigned u0, v0, w0;
unsigned u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u > > 16;
v0 = v & 0xFFFF; v1 = v > > 16;
w0 = u0*v0;
t = u1*v0 + (w0 > > 16);
w1 = t & 0xFFFF;
w2 = t > > 16;
w1 = u0*v1 + w1;
// x为高32位, y为低32位
unsigned x = u1*v1 + w2 + (w1 > > 16);
unsigned y = u*v;
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
}
#7
重传一下
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
#8
if((x | t) > = z) { x -= z; y++; }
#9
好像没那么简单,呵呵.
#1
能内嵌汇编不能?
#2
想办法手工处理一个进位和借位就是了。
#3
考虑用数组 看行不
#4
直接在网上找大数运算之类的类 吧。
#5
大数运算,支持任意长度的 + - * / %
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx
#6
我看到了一段代码挺好的,能实现 a*b/c的功能,
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下
// 计算(u*v)%m
unsigned mul_mod(unsigned u, unsigned v, unsigned z)
{
// 如果u*v没有溢出, 则直接计算
if((u*v)/u == v) return (u*v)%z;
// 进行长乘法(结果为64位)
unsigned u0, v0, w0;
unsigned u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u > > 16;
v0 = v & 0xFFFF; v1 = v > > 16;
w0 = u0*v0;
t = u1*v0 + (w0 > > 16);
w1 = t & 0xFFFF;
w2 = t > > 16;
w1 = u0*v1 + w1;
// x为高32位, y为低32位
unsigned x = u1*v1 + w2 + (w1 > > 16);
unsigned y = u*v;
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
}
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下
// 计算(u*v)%m
unsigned mul_mod(unsigned u, unsigned v, unsigned z)
{
// 如果u*v没有溢出, 则直接计算
if((u*v)/u == v) return (u*v)%z;
// 进行长乘法(结果为64位)
unsigned u0, v0, w0;
unsigned u1, v1, w1, w2, t;
u0 = u & 0xFFFF; u1 = u > > 16;
v0 = v & 0xFFFF; v1 = v > > 16;
w0 = u0*v0;
t = u1*v0 + (w0 > > 16);
w1 = t & 0xFFFF;
w2 = t > > 16;
w1 = u0*v1 + w1;
// x为高32位, y为低32位
unsigned x = u1*v1 + w2 + (w1 > > 16);
unsigned y = u*v;
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
}
#7
重传一下
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
// 进行长除法(被除数为64位)
for (int i = 1; i <= 32; i++)
{
t = (int)x > > 31; // All 1 's if x(31) = 1.
x = (x < < 1) | (y > > 31); // Shift x || y left
y < <= 1; // one bit.
if((x|t) > = z) { x -= z; y++; }
}
return x; // y为商, x为余数
#8
if((x | t) > = z) { x -= z; y++; }
#9
好像没那么简单,呵呵.