我必须乘以2个大整数,每个都是80+位数。
这类任务的一般方法是什么?
答案 0 :(得分:3)
您必须使用大型整数库。维基百科的任意精度算术页here
中列出了一些开源的答案 1 :(得分:2)
我们忘记了CPU可以将适合单个寄存器的数字相乘是多么棒。一旦你试图将两个大于寄存器的数字相乘,你就会意识到实际上乘以数字是多么痛苦。
我不得不写一段很长的课。这是我的乘法函数的代码。 KxVector只是一个32位值的数组,带有计数,并且非常自我解释,并不包括在这里。为简洁起见,我删除了所有其他数学函数。除乘法和除法外,所有数学运算都很容易实现。
#define BIGNUM_NEGATIVE 0x80000000
class BigNum
{
public:
void mult( const BigNum& b );
KxVector<u32> mData;
s32 mFlags;
};
void BigNum::mult( const BigNum& b )
{
// special handling for multiply by zero
if ( b.isZero() )
{
mData.clear();
mFlags = 0;
return;
}
// apply sign
mFlags ^= b.mFlags & BIGNUM_NEGATIVE;
// multiply two numbers using a naive multiplication algorithm.
// this would be faster with karatsuba or FFT based multiplication
const BigNum* ppa;
const BigNum* ppb;
if ( mData.size() >= b.mData.size() )
{
ppa = this;
ppb = &b;
} else {
ppa = &b;
ppb = this;
}
assert( ppa->mData.size() >= ppb->mData.size() );
u32 aSize = ppa->mData.size();
u32 bSize = ppb->mData.size();
BigNum tmp;
for ( u32 i = 0; i < aSize + bSize; i++ )
tmp.mData.insert( 0 );
const u32* pb = ppb->mData.data();
u32 carry = 0;
for ( u32 i = 0; i < bSize; i++ )
{
u64 mult = *(pb++);
if ( mult )
{
carry = 0;
const u32* pa = ppa->mData.data();
u32* pd = tmp.mData.data() + i;
for ( u32 j = 0; j < aSize; j++ )
{
u64 prod = ( mult * *(pa++)) + *pd + carry;
*(pd++) = u32(prod);
carry = u32( prod >> 32 );
}
*pd = u32(carry);
}
}
// remove leading zeroes
while ( tmp.mData.size() && !tmp.mData.last() ) tmp.mData.pop();
mData.swap( tmp.mData );
}
答案 2 :(得分:1)
这取决于你想要对数字做什么。您想使用更多算术运算符,还是只想将两个数相乘,然后将它们输出到文件中?如果是后者,将数字放在int或char数组中然后实现一个乘法函数就好了,就像你学会了用手做乘法一样。
如果您想在C中执行此操作,这是最简单的解决方案,但当然它的内存效率不高。我建议为C ++寻找Biginteger库,e.g.如果你想做更多,或者只是自己实现它以满足你的需求。