如何将大整数转换为基数 2^32?
首先,我是为自己做这件事,所以请不要建议“使用 GMP / xint / bignum”(如果它适用的话)。
我正在寻找一种将大整数(例如超过 9000 位数字)转换为 232 表示形式的 int32 数组的方法。这些数字将以 10 为基数的字符串开始。
例如,如果我想将刚刚超过 INT_MAX
的 string a = "4294967300"
(以 10 为基数)转换为新的基数 232< /sup> 数组,则为 int32_t b[] = {1,5}
。如果 int32_t b[] = {3,2485738}
,则以 10 为基数的数字将为 3 * 2^32 + 2485738
。显然,我将使用的数字甚至超出了 int64 的范围,因此我无法准确地将字符串转换为整数并修改我的成功方式。
我有一个以 10 为基数进行减法的函数。现在我想我只需执行 subtraction(char* number, "2^32")
并计算在得到 a 之前有多少次负数,但对于较大的数字可能需要很长时间。
有人可以建议一种不同的转换方法吗?谢谢。
编辑
抱歉,如果您没有看到该标签,我正在使用 C++
First off, I'm doing this for myself so please don't suggest "use GMP / xint / bignum" (if it even applies).
I'm looking for a way to convert large integers (say, OVER 9000 digits) into a int32 array of 232 representations. The numbers will start out as base 10 strings.
For example, if I wanted to convert string a = "4294967300"
(in base 10), which is just over INT_MAX
, to the new base 232 array, it would be int32_t b[] = {1,5}
. If int32_t b[] = {3,2485738}
, the base 10 number would be 3 * 2^32 + 2485738
. Obviously the numbers I'll be working with are beyond the range of even int64 so I can't exactly turn the string into an integer and mod my way to success.
I have a function that does subtraction in base 10. Right now I'm thinking I'll just do subtraction(char* number, "2^32")
and count how many times before I get a negative number, but that will probably take a long time for larger numbers.
Can someone suggest a different method of conversion? Thanks.
EDIT
Sorry in case you didn't see the tag, I'm working in C++
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
假设您的 bignum 类已经具有乘法和加法,则相当简单:
转换另一种方式是相同的概念,但需要除法和模数
这两者都仅适用于无符号。
Assuming your bignum class already has multiplication and addition, it's fairly simple:
Converting the other way is the same concept, but requires division and modulo
Both of these are for unsigned only.
要将基数为 10 的字符串转换为您的编号系统,请从零开始继续将每个基数 10 数字与 10 相加和相乘。每次有进位时,都会向基数 2^32 数组添加一个新数字。
To convert from base 10 strings to your numbering system, starting with zero continue adding and multiplying each base 10 digit by 10. Every time you have a carry add a new digit to your base 2^32 array.
最简单(不是最有效)的方法是编写两个函数,一个将一个大数乘以一个 int,另一个将一个 int 添加到一个大数。如果您忽略有符号数字引入的复杂性,代码看起来像这样:(
为了清楚起见,编辑使用向量并为实际问题添加代码)
然后,使用这些函数实现atobignum()是微不足道的:
The simplest (not the most efficient) way to do this is to write two functions, one to multiply a large number by an int, and one to add an int to a large number. If you ignore the complexities introduced by signed numbers, the code looks something like this:
(EDITED to use
vector
for clarity and to add code for actual question)Then, implementing atobignum() using those functions is trivial:
我认为Docjar:gnu/java/math/MPN.java 可能包含您要查找的内容,特别是
public static int set_str (int dest[], byte[] str, int str_len, int base)
的代码。I think Docjar: gnu/java/math/MPN.java might contain what you're looking for, specifically the code for
public static int set_str (int dest[], byte[] str, int str_len, int base)
.首先将数字转换为二进制。从右边开始,每组 32 位都是一个 base2^32 数字。
Start by converting the number to binary. Starting from the right, each group of 32 bits is a single base2^32 digit.