我有这段代码

#include <iostream>

using namespace std;

int main(int argc,char **argv) {

    unsigned long long num1 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995LL;
    unsigned long long num2 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996LL;
    unsigned long long num3 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997LL;
    unsigned long long num4 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998LL;
    unsigned long long num5 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999LL;

    cout << (unsigned long long)(num1 * num2 * num3 * num4 * num5) << endl;
    return 0;
}

正如你所看到的数字是巨大的,但是当我在那里进行数学计算时,我得到了这个: 18446744073709551496

在编译时我收到这些警告:

warning: integer constant is too large for its type|
In function `int main(int, char**)':|
warning: this decimal constant is unsigned only in ISO C90|
...
有帮助吗?

解决方案

您的结果大于long long类型 - 您需要查看 BigInteger 或任意精度库,像 gmp

其他提示

这些数字不适合任何C ++数据类型。如果您只想打印它们,请将数字存储在字符串中。如果你想对它进行数学运算,找一个任意精度的数学库并使用它。

如果你想在你的代码中使用这么大的文字,你必须将它们作为字符串文字输入并将它们加载到某种类型的BigInt类中。现在没有办法表达源代码中那么大的整数文字(虽然C ++ 0x有望解决这个不足)。

如果您正在使用 BigInteger 库,请查看 stringToBigUnsigned BigIntegerUtils.hh 中的code> function。

#include "BigUnsigned.hh"
#include "BigIntegerUtils.hh"     

 BigUnsigned  num1 = stringToBigUnsigned (
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999999999999999999999999999999999999999999999999"
    "99999999999999999999999999999999999995"
    );

你想做什么?你了解二进制和十进制数字的基础知识吗?为什么8位只保存值0到255,12位0-4095等?保留您感兴趣的号码需要多少位?或者更好的是,你有多大兴趣创造?你使用9s来增加数字吗?那么十六进制0xF ......呢?如果你想要最大的无符号数(在一个标准整数类型中),为什么不:

unsigned long long a,b;

a = -1; //只是看似错误混合有符号和无符号但它有效,数字在存储之前转换为无符号

b = 0; b--; //与上面的内容相同

你真的需要那个级别的精度吗?您意识到乘法可能需要两倍于每个操作数的结果? 0xFF * 0xFF = 0xFE01,如果在这种情况下你使用的是8位整数,则无法进行数学计算。当你继续乘以0xFF * 0xFF * 0xFF = 0xFD02FF时,情况会变得更糟。

试图做什么?


看到你的回复:

我以前没见过8号欧拉。听起来像是一个很好的面试问题,因为它只需要几行代码来解决。


您的其他回复:

...编号

可能因为我们有10个手指(也许是10个脚趾),我们长大了“基数10”。我们的时钟大部分都是基础60,但它与基数10混合使其更加混乱。无论如何,基数10,表示每个数字占位符,您有10个唯一数字之一,当您达到该位置的最大值时,您将转到下一个位置。这是所有小学的东西。

000结果 001结果 002结果 003结果 ...点击 008结果 009结果 010结果 011结果 012结果 ......

查看最右边的数字如何有10个符号(0,1,2,3,4,5,6,7,8,9),当它到达最后一个符号时,它重新开始,而左边的一个它增加1。所有基本编号系统都适用此规则。

除了只有两个符号0和1

之外,基数2都是如此

000结果 001结果 010结果 011结果 100个结果 101个结果 ......

对于八进制也是如此,但是8个符号(0,1,2,3,4,5,6,7)

000结果 001结果 002结果 003结果 004结果 005结果 006结果 007结果 010结果 011结果 012结果 013结果 ......

十六进制也是如此,16个符号(0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f)

000结果 001结果 002结果 003结果 004结果 005结果 006结果 007结果 008结果 009结果 00A点击 00B点击 00C点击 00D结果 00E结果 00F结果 010结果 011结果 012结果 013结果 ......

我打算在计算机中使用二进制代替其他基础(如10)。底线很容易打开或关闭两个状态,或者高和低。两个状态就像基座2中的两个符号1和0.试图将电子器件调谐到可用电压范围内的两个以上状态是困难的,至少过去是这样,保持接近零伏特或高于一些小的伏特是相对容易,因此数字电子使用两种状态,二进制。

即使是二进制人类的简单任务也是冗长的,简单的二年级数学仍然是很多的零和零。所以八进制变得流行,因为它允许你以三位为一组进行思考,你可以使用我们熟悉的符号作为数字0,1,2,3,4,5,6,7。但是四个一组是另一个2的幂,给人类比八进制更多的心算计算能力,十六进制基于4位,也是2的幂。我们不得不在我们借用的10中添加更多的符号。传统的阿拉伯语基础10,所以使用了前6个字母表。如果使用Octal很少,如果他们认为八角形而不是十六进制,你可以告诉某人年龄。 (我来自十六代,但是与那些与十六进制斗争的八代人合作,因为他们无法从八进制到二进制到十六进制)。

计算中的基数为10r就像十六进制的普通人类思维。计算机不做基数10(对于他们曾经做过bcd的懒人),他们做基数2.计算机中的十进制数1234实际上是0x4D2或0b010011010010。这是一个值,比如说你想要添加1234加上你需要的其他数字,这与symbos 1,2,3和4无关。但是要在stackoverflow上发布这个答案,我们不使用数字我们使用ASCII,因此ascii中的1234是0x31,0x32,0x33,0x34,这对于你的euler解决方案很重要,假设1000位数字是作为ascii字符串提供的,它必须是或者你必须转换它从二进制到ascii,因为问题是一个基本问题而不是定义的基础2。

回到我的要求。假设您有4位内存来存储一个数字,您可以存储多少个数字?如果你认为10号基数你可能认为这个数字是9,因为你被训练考虑使用每个存储位置中的最大符号,如果你在基数10中有5个存储位置,则99999是最大数字。返回4位但是,单个位的最大符号是1,将该数字放在每个存储位置1111(四个)。只要看看这四个,你就可以在脑海中轻松看到相同数字17八进制或十六进制的八进制和十六进制版本。要查看十进制需要数学,或者在这种情况下记忆,该数字是15十进制。所以你可以拥有的最大四位数是0xF或15不是9. 8位数怎么样? 0xFF或255(2到8次幂减去1)。最大的16位数? 65535等。

所以,当我问你想要使用多少位时,这就是我的意思。看看这个数字99999.再次基数10,你会认为这是最大的数字,但对于计算机它只是那里的一部分,99999十进制是0x1869F,需要17位内存来存储,最大的17位数你可以store是0x1FFFF,这是131071,比99999大一点。所以当你想在计算机上考虑大数和数学时,你必须考虑二进制(或十六进制)。

最初你在进行乘法运算,这仍然是欧拉问题的一部分,但我所询问的是与精度和位存储有关。以下是一些基础知识,我不会介绍它,但你可以看到为什么我们依赖计算机中的浮点单元。

取最大4位数1111(二进制),即十进制15。添加具有最大四位数的那个,你得到15 + 15 = 30 = 0x1E或11110二进制。因此,要添加两个四位数字,您需要五位来保持答案。计算机保持“携带”状态。这个额外的位。本质上,计算机中的加/减整数数学函数允许您有N + 1位。因此,如果它是32位计算机,你基本上有33位用于加/子数学。

问题是多重和分裂,即使在今天许多处理器也不支持(是的,许多处理器没有fpu,只做加法和减法,有时会成倍增加,但除法很少。乘法和除法需要很多电子设备的权衡你可以用软件中的加法和减法来完成它们吗?采用最坏情况乘以4位系统 1111 * 1111 = 11100001所以需要8位来存储4位乘法的结果,你会很快发现,如果你有一个4位系统MOST你想要做的乘法将得到一个无法存储在4中的数字位。因此,当我看到你采用64位整数(无符号长整数通常是64位)并乘以四次,这意味着你需要64 * 5或320位整数来存储你的答案,你试图把这个答案放在一个64大结果,这通常取决于编译器和计算机将很乐意做,并将截断高位,留下你的结果的低64位,这可能很容易看起来比你的任何操作数小,这是wh

你得到的答案,18446744073709551496,是由于你的999 ... 9s被分配到一个很长的长,加上多个操作溢出。它具有确定性,但实际上只是随机的比特集合。

unsigned int表示系统字。今天,根据您的系统是32位还是64位,该字最大值为2 ^ 32 -1或2 ^ 64 - 1。你正在上限。

你必须写一个bignum类或使用'net。

你为什么要这样做?

这些数字不适合 unsigned long long 范围,所以要么你可以使用GMP库,要么使用字符串代表大数字,就像我用来计算50的数字阶乘一样:

http://codepad.org/bkWNV0JC

#include <cmath>
#include <iostream>
using namespace std;
int main()
{
  unsigned int nd, nz;   
  unsigned char *ca;   
  unsigned int j, n=50, q, temp;
  int i;
  double p;
    p = 0.0;
    for(j = 2; j <= n; j++)
    {
      p += log10((double)j);  
    }
    nd = (int)p + 1;

    ca = new unsigned char[nd+1];
    if (!ca)
    {
      cout << "Could not allocate memory!!!";
      exit(0);
    }
    for (i = 1; (unsigned)i < nd; i++)
    {
      ca[i] = 0;
    }
    ca[0] = 1;

    p = 0.0;
    for (j = 2; j <= n; j++)
    {
      p += log10((double)j);   
      nz = (int)p + 1;        
      q = 0;                  
      for (i = 0;(unsigned) i <= nz; i++)
      {
        temp = (ca[i] * j) + q;
        q = (temp / 10);
        ca[i] = (char)(temp % 10);
      }
    }

    cout << "\nThe Factorial of " << n << " is: ";
    for( i = nd - 1; i >= 0; i--)
    {
      cout << (int)ca[i];
    }
  //  delete []ca;    
  return 0;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top