如何将大整数转换为基数2^32

How to convert large integers to base 2^32?

本文关键字:转换 整数      更新时间:2023-10-16

首先,我是为自己做这件事的,所以请不要建议"使用GMP/xint/bignum"(如果适用的话(。

我正在寻找一种方法,将大整数(例如,超过9000位数字(转换为232表示的int32数组。数字将以10为基数的字符串开始。

例如,如果我想将刚刚超过INT_MAXstring a = "4294967300"(在基数10中(转换为新的基数232数组,那么它将是int32_t b[] = {1,5}。如果是int32_t b[] = {3,2485738},则基数10将是3 * 2^32 + 2485738。很明显,我将要处理的数字超出了偶数int64的范围,所以我无法将字符串精确地转换为整数,从而成功。

我有一个函数,用10做减法。现在我想我只需要做subtraction(char* number, "2^32"),计算多少次就可以得到负数,但对于更大的数字,这可能需要很长时间。

有人能提出一种不同的转换方法吗?谢谢

编辑
很抱歉,如果你没有看到标签,我正在C++

中工作

假设bignum类已经有乘法和加法,那么它相当简单:

 bignum str_to_big(char* str) {
     bignum result(0);
     while (*str) {
         result *= 10;
         result += (*str - '0');
         str = str + 1;
     }
     return result;
 }

以另一种方式转换是相同的概念,但需要除法和模

std::string big_to_str(bignum num) {
    std::string result;
    do {
        result.push_back(num%10);
        num /= 10;
    } while(num > 0);
    std::reverse(result.begin(), result.end());
    return result;
}

这两个都只适用于无符号。

要将以10为基数的字符串转换为您的编号系统,请从零开始,继续将每个以10为基点的数字相加并乘以10。每次进位时,都要在基数2^32数组中添加一个新数字。

实现这一点的最简单(不是最高效(方法是编写两个函数,一个是将一个大数字乘以一个int,另一个是向一个大数值添加一个int。如果你忽略了有符号数字带来的复杂性,代码看起来像这样:

(为了清晰起见,使用vector进行编辑,并为实际问题添加代码(

void mulbig(vector<uint32_t> &bignum, uint16_t multiplicand)
{
    uint32_t carry=0;
    for( unsigned i=0; i<bignum.size(); i++ ) {
        uint64_t r=((uint64_t)bignum[i] * multiplicand) + carry;
        bignum[i]=(uint32_t)(r&0xffffffff);
        carry=(uint32_t)(r>>32);
    }
    if( carry )
        bignum.push_back(carry);
}
void addbig(vector<uint32_t> &bignum, uint16_t addend)
{
    uint32_t carry=addend;
    for( unsigned i=0; carry && i<bignum.size(); i++ ) {
        uint64_t r=(uint64_t)bignum[i]  + carry;
        bignum[i]=(uint32_t)(r&0xffffffff);
        carry=(uint32_t)(r>>32);
    }
    if( carry )
        bignum.push_back(carry);
}

然后,使用这些函数实现atobignum((是微不足道的:

void atobignum(const char *str,vector<uint32_t> &bignum)
{
    bignum.clear();
    bignum.push_back(0);
    while( *str ) {
        mulbig(bignum,10);
        addbig(bignum,*str-'0');
        ++str;
    }
}

我认为Docjar:gnu/java/math/MPN.java可能包含您想要的内容,特别是public static int set_str (int dest[], byte[] str, int str_len, int base)的代码。

首先将数字转换为二进制。从右边开始,每组32位是一个以2^32为基数的单个数字。