如何在基数2 ^ 32中表示数字?

如果我有一个基数为10或基数为16的数字,如何将其更改为2 ^ 32?

我试图这样做的原因是为了实现其他成员在这里建议的BigInt .. 为什么要使用更高的基数来实现BigInt?

它是否与整数(基数10)相同,直到2 ^ 32? 它之后会发生什么?

您正试图找到某种forms的东西

 a0 + a1 * (2^32) + a2 * (2^32)^2 + a3 * (2^32)^3 + ... 

正是 base-2 32系统的定义,所以请忽略所有告诉你问题没有意义的人!

无论如何,你所描述的被称为基本转换 。 有快捷的方法,有简单的方法来解决这个问题。 快速的方法非常复杂(有专门讨论这个主题的书籍的全部章节 ),我不打算在这里尝试解决它们(尤其是因为我从未试图使用它们)。

一种简单的方法是首先在数字系统中实现两个函数,乘法和加法。 (即实现BigInt add(BigInt a, BigInt b)BigInt mul(BigInt a, BigInt b) )。 一旦你解决了这个问题,你会注意到一个10号基数可以表示为:

 b0 + b1 * 10 + b2 * 10^2 + b3 * 10^3 + ... 

也可以写成:

 b0 + 10 * (b1 + 10 * (b2 + 10 * (b3 + ... 

因此,如果您在输入字符串中从左向右移动,则可以一次剥离一个基数为10的数字,并使用addmul函数累积到BigInt

 BigInt a = 0; for each digit b { a = add(mul(a, 10), b); } 

免责声明:此方法的计算效率高,但至少可以帮助您入门。

注意:从base-16转换简单得多,因为2 32是16的精确倍数。因此转换基本上归结为连接位。

我们假设我们正在谈论一个基数为10的数字:

 a[0]*10^0 + a[1]*10^1 + a[2]*10^2 + a[3]*10^3 + ... + a[N]*10^N 

其中每个a[i]是0到9范围内的数字。

我将假设您可以解析作为输入值的字符串并找到数组a[] 。 一旦你能做到这一点,并假设你已经使用+*运算符实现了BigInt类,那么你就回家了。 您可以使用BigInt类的实例简单地评估上面的表达式。

您可以使用Horner方法相对有效地评估此表达式。

我刚刚把它写下来,我敢打赌,有更高效的基本转换方案。

如果我有一个基数为10或基数为16的数字,如何将其更改为2 ^ 32?

就像你将它转换为任何其他基础一样。 你想把数字n写为

 n = a_0 + a_1 * 2^32 + a_2 * 2^64 + a_3 * 2^96 + ... + a_k * 2^(32 * k). 

因此,找到分成n的最大2 ^ 32的幂,从n减去该幂的倍数,并重复差值。

但是,你确定你问的是正确的问题吗?

我怀疑你的意思是问一个不同的问题。 我怀疑你的意思是问:我如何将一个基数为10的数字解析为我的BigInteger实例? 这很简单。 编写您的实现代码,并确保您已实现+* 。 我完全不知道你如何在内部表示整数,但是如果你想使用base 2 ^ 32,那就好了。 然后:

  BigInteger Parse(string s) { BigInteger b = new BigInteger(0); foreach(char c in s) { b = b * 10 + (int)c - (int)'0'; } return b; } 

我会留给你把它翻译成C.

基座16很容易,因为2 32是16 8 ,精确的功率。 因此,从最低有效数字开始,一次读取8个base-16数字,将这些数字转换为32位值,这是下一个基数为2的32 “数字”。

基数10更难。 如你所说,如果它小于2 32 ,那么你只需将该值作为单个基数-2 32 “数字”。 否则,我能想到的最简单的方法是使用Long Division算法重复地将base-10值除以2 32 ; 在每个阶段,剩余部分是下一个基数-2 32 “数字”。 也许比我更了解数论的人可以提供更好的解决方案。

我认为这是一件非常合理的事情。

你正在做的是在32位整数数组中表示一个非常大的数字(如加密密钥)。

基数16表示是基数2 ^ 4,或一次4比特的一系列。 如果您正在接收基数16“数字”的流,请填入数组中第一个整数的低4位,然后填写下一个最低位,直到您读取8“数字”。 然后转到数组中的下一个元素。

 long getBase16() { char cCurr; switch (cCurr = getchar()) { case 'A': case 'a': return 10; case 'B': case 'b': return 11; ... default: return cCurr - '0'; } } void read_input(long * plBuffer) { long * plDst = plBuffer; int iPos = 32; *(++plDst) = 0x00; long lDigit; while (lDigit = getBase16()) { if (!iPos) { *(++plDst) = 0x00; iPos = 32; } *plDst >> 4; iPos -= 4; *plDst |= (lDigit & 0x0F) << 28 } } 

有一些修复工作要做,比如通过iPos移动* plDst结束,并跟踪数组中的整数数量。

从基地10转换也有一些工作。

但这足以让你开始。