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

时间:2011-11-02 21:16:34

标签: c++ largenumber

首先,我正在为自己这样做,所以请不要建议“使用GMP / xint / bignum”(如果它甚至适用)。

我正在寻找一种方法将大整数(例如,超过9000位数)转换为2个 32 表示的int32数组。这些数字将从10个字符串开始。

例如,如果我想将string a = "4294967300"(在基数10中)(刚好超过INT_MAX)转换为新的基数2 32 数组,那么它将是int32_t b[] = {1,5}。如果int32_t b[] = {3,2485738},则基数为3 * 2^32 + 2485738。显然,我将使用的数字超出了int64的范围,因此我无法将字符串精确地转换为整数并改变成功的方式。

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

有人可以提出不同的转换方法吗?感谢。

修改
对不起,如果您没有看到标签,我正在使用 C ++

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

假设你的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;
}

这两个都是仅用于无符号的。

答案 2 :(得分:1)

最简单(不是最有效)的方法是编写两个函数,一个用于将一个大数乘以一个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;
    }
}

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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