uint64_t上的计算结果错误

时间:2014-09-02 13:45:20

标签: c linux math 64-bit

上下文

Debian 64bits。

我有这段代码

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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

    uint64_t b = 5000000000;/* 5 000 000 000 */
    uint64_t a = (b*b)/2;

    printf("a = %llu\n",a);

return 0;
}

问题

我的操作系统中的Javascript,我的手动计算器和虚拟计算器给出了1.25×10 ^ 19的结果,而我上面的c程序给出了= 3276627963145224192

我做错了什么?

3 个答案:

答案 0 :(得分:1)

b*b的中间操作的值大于64位寄存器可以容纳的值,因此溢出。

因此,b (= 5 000 000 000) > 2^32因此b*b > 2^64

并且,由于5000000000 * 5000000000 / 2永远不能适合64位变量,因此如果不使用特殊方法(如使用数组表示数字),则无法在C中计算此值。

此外,正如@Joachim Pileborg建议的那样,您应该将unsigned long long值指定为b

uint64_t b = 5000000000ull;

答案 1 :(得分:1)

uint64_t无法保留b*b的结果。

b*b的结果是25000000000000000000.那是25x10 ^ 18。

但是uint64_t可以保持最大值达到6553255926290448384.因此b*b操作会发生溢出。

由于这种溢出,你没有得到实际的结果!

答案 2 :(得分:0)

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

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

    uint64_t b = 5000000000LL;/* 5 000 000 000 */
    uint64_t a = (((uint64_t)b)*b)/2LL;

    printf("a = %llu\n",a);

return 0;
}