如何用2 ^ 32表示基数?

时间:2012-04-16 19:29:11

标签: c++ c numbers

如果我有一些10号或16号基数,我该怎么把它改成2 ^ 32?

我试图这样做的原因是按照其他成员的建议实现BigInt。Why to use higher base for implementing BigInt?

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

5 个答案:

答案 0 :(得分:12)

您正试图找到某种形式

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

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

无论如何,你所描述的内容被称为base conversion。有快速的方法,有简单的方法来解决这个问题。快速方式非常复杂(有entire chapters of books致力于主题),我不打算在这里尝试解决它们(尤其是因为我从未尝试过使用它们)。

一种简单的方法是首先在数字系统中实现两个函数,乘法和加法。 (即实施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函数累积到您的{ {1}}:

BigInt

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

注意:从base-16转换更多更简单,因为2 32 是16的精确倍数。所以转换基本上来了直到连接位。

答案 1 :(得分:5)

我们假设我们正在谈论一个基数为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's method相对有效地评估此表达式。

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

答案 2 :(得分:4)

  

如果我有一些基数为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.

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

我认为这是完全合理的事情。

您正在做的是在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
  }
}

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

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

但这足以让你开始。