5

我正在用 C 语言构建一个程序,它可以获得2. 用户输入 的值n,程序计算2^n

这是代码

当我输入问题时100

我得到了什么:

1,267,650,600,228,229,400,000,000,000,000

我应该得到什么

1,267,650,600,228,229,401,496,703,205,376

它必须完全用 ANSI C 编码。关于如何提高精度的任何想法?的最大值N必须是256(我想是 256 位,这意味着最大输出应该是2^256)。

我在这里缺乏的是精确性,我不知道如何解决这个问题。有任何想法吗?

4

7 回答 7

4

我认为如果你从一开始就在 10 号基地工作是最简单的。这是因为虽然以二进制计算 2 的幂是微不足道的,但转换回以 10 为基数要困难得多。

如果您有一个以 10 为底的数字1的数组,则只需使用进位实现以 10 为底的加法即可乘以 2(通过将数字添加到自身)。循环执行这些n时间,您就会得到答案。

如果您希望支持更高的指数,您还可以考虑通过平方来实现求幂,但这更难,因为您需要一般乘法,而不仅仅是乘以 2。

1提示:如果您以相反的顺序存储数字会更方便。

于 2012-11-01T03:13:00.360 回答
2

这是我对hammar方法的快速而肮脏的实施。,将十进制数存储为 C 字符串,其中的数字以相反的顺序排列。

在ideone上运行代码

void doubleDecimal(char * decimal)
{
    char buffer[256] = "";
    char c;
    unsigned char d, carry = 0;
    int i = 0;

    while (c = decimal[i])
    {
        d = 2 * (c - '0') + carry;
        buffer[i] = (d % 10) + '0';
        carry = d / 10;
        i++;
    }

    if (carry > 0)
        buffer[i++] = (carry % 10) + '0';

    buffer[i] = '\0';
    strncpy(decimal, buffer, 256);
}

void reverse(char * str)
{
    int i = 0;
    int j = strlen(str) - 1;

    while (j > i)
    {
        char tmp = str[i];
        str[i] = str[j];
        str[j] = tmp;

        i++;
        j--;
    }
}

int main(void)
{
    char decimal[256] = "1";
    int i;

    for (i = 0; i < 100; i++)
        doubleDecimal(decimal);

    reverse(decimal);
    printf("%s", decimal);

    return 0;
}

输出:

1267650600228229401496703205376
于 2012-11-01T03:42:34.063 回答
1

double 是(可能)64位值。您不能将 256 位精度存储在 64 位中。你得到一个接近的数字的原因是因为浮点数以不同的精度存储——不是所有的连续数字都可以表示,但你可以表示非常大的数字。在这种情况下非常没用。您想要的是使用任意精度库,或者由于这可能是家庭作业,您应该编写自己的。

于 2012-11-01T02:49:49.540 回答
1

double使用 64 位 IEEE 754的典型具有大约 51 位精度 IIRC。

最有可能支持高达 256 的指数的目的是超过该精度,以及 a long doubleor的精度long long,因此您必须自己做事。

那么,作为家庭作业,

  • 将十进制数字值存储在数组中 + 数字计数
  • 实现此类数组中的值加倍 + 计数
  • 以 1 和 double 值开始适当的次数。
于 2012-11-01T03:11:14.923 回答
0

您需要考虑一些事情来解决这个问题:

  1. 您只处理整数,因此您应该使用整数表示(您需要自己滚动,因为您不能使用“仅”64 位长的 long long)。
  2. 你说的 2 的幂 - 多么方便 - 计算机使用 2 的幂存储数字(你只需要使用移位操作和位摆弄......不需要乘法)。
  3. 如何将基数为 2 的数字转换为基数为 10 的数字以进行显示(考虑除法并一次输出一个数字(考虑硬件除数的作用以使位操作正确)。
于 2012-11-01T03:02:34.280 回答
0

您不能将 256 位精度存储在 64 位中。您要关闭数字的原因是因为浮点数以不同的精度存储。可以表示所有连续的数字,但可以表示非常大的数字。在这种情况下非常没用。

于 2012-11-01T03:06:58.173 回答
0
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//constants
#define MAX_DIGITS 1000

//big integer number struct
struct bigint {
  char Digits[MAX_DIGITS];
};

//assign a value
void assign(struct bigint* Number,int Value) {
  if (Value!=1) {
    printf("Can not assign value other than 1\n");
    exit(0);
  }
  memset(Number,0,sizeof(bigint));
  Number->Digits[0] = Value;
}

//multiply the big integer number with value
void multiply(struct bigint* Number,int Value) {
  int Digit,New_Digit;
  int Carry = 0;

  for (int Index=0; Index<MAX_DIGITS; Index++) {
    Digit     = Number->Digits[Index];
    New_Digit = Digit*Value%10;
    if (New_Digit+Carry<10) {
      New_Digit = New_Digit+Carry;
      Carry     = Digit*Value/10;
    }
    else {
      New_Digit = (New_Digit+Carry)%10;
      Carry     = (Digit*Value/10)+1;
    }

    //set the new digit
    Number->Digits[Index] = New_Digit;
  }//for loop
}

//print out the value of big integer type
void print(struct bigint* Number) {
  int Index = MAX_DIGITS-1;
  while (Number->Digits[Index]==0 && Index>=0)
    Index--;

  //the big integer value is zero
  if (Index==-1) {
    printf("0");
    return;
  }

  while (Index>=0) {
    printf("%u",Number->Digits[Index]);
    Index--;
  }
}

//main programme entry point
int main(int Argc,char** Args) {
  int Power = 100;
  struct bigint Number;

  //assign the initial value
  assign(&Number,1);

  //do the multiplication
  for (int Index=0; Index<Power; Index++)
    multiply(&Number,2);

  //print result
  print(&Number);
  getch();
}

//END-OF-FILE
于 2012-11-01T03:38:25.233 回答