长期计算问题

时间:2012-12-07 23:06:35

标签: c

我有遍历数字的代码并创建该整数的字符数组表示。所以对于1234这样的数字,我得到的数组看起来像{'1','2','3','4'}

部分代码如下所示:

do {
   //print here
     c[i++] = (char)(((int)'0')+(num - (num/10)*10 ));
} while ((num = num/10) != 0);

我遇到像long long int这样的大数据类型的问题:18446612134627563776

我在循环中打印的值是:

18446612134627563776
18446730879801352832
18446742754318731738
...
18446744073709551615

值应为

18446612134627563776
1844661213462756377
184466121346275637
...
18
1

奇怪的是循环终止了。最后打印的值是18446744073709551615 != 0,因此不确定它为什么会在那里终止。我认为它的数据类型有些问题,我说得不对。

这是印刷声明:

printk("long=%llu sec=%llu , char=%c\n", num, (num/10)*10, (char)(((int)'0')+((num - (num/10)*10 ))));

4 个答案:

答案 0 :(得分:2)

你的代码很好。问题是num的类型已签名(即只有long long)。将其改为(unsigned long long)你应该好好去。

答案 1 :(得分:1)

  

long long int:18446612134627563776

long long int是一种带符号的类型,通常为64位宽,具有最大可表示数

2^63-1 = 9223372036854775807

你的价值大于那个,并且溢出,可能是

2^63 - 18446612134627563776 = -131939081987840

打印值

2^64 + (-131939081987840)/(10^k)

将类型更改为unsigned long long以获得预期结果。

答案 2 :(得分:0)

为什么不使用模运算符来计算除法的余数以获得最后一位数?

下面的整数

do {
    c[i++] = (char)(((int)'0')+(num %10 ));
} while ((num = (num/10)) != 0);

答案 3 :(得分:0)

它不会溢出,我用这段代码测试过它。

unsigned long long num = 18446612134627563776;
char c[100];
unsigned int i = 0;

do {
    //print here
    c[i++] = '0'+ (char)(num - (num/10)*10 );
} while ((num = num/10) != 0);

c[i] = '\0';
cout << c << endl;

问题是编译器可能尝试将10用作int,并且在转换时遇到问题。投入后,它实际上是有效的。问题是该算法是向后的,因为它将带来6,然后是7等......输出如上所述,与铸造完全相同,除了铸造之外。

这是实际代码和实际输出。

677365726431221664481

希望这会有所帮助: - )