首先,我正在为自己这样做,所以请不要建议“使用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 ++
答案 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位。