64位移位的错误答案

时间:2014-10-23 20:22:13

标签: c gcc bit-manipulation

这是我的代码:

#include <stdio.h>
#include <inttypes.h>

int main()
{
    uint64_t a = 1000000000;
    printf("%" PRIu64 "\n", a << 40);
    return 0;
}

此代码返回

11153727427136454656

正确答案是1099511627776000000000

这里发生了什么?我在64位Ubuntu 12.04上使用gcc 4.8.1进行编译。

1 个答案:

答案 0 :(得分:12)

1000000000 << 40数学结果为1099511627776000000000,超过2 64 -1(实际上超过2 69 )并且不能表示为uint64_t

对于带符号的左操作数,这将是一个导致未定义行为的溢出。对于无符号左操作数,结果减少模2 N ,其中N是左操作数的类型的宽度(在这种情况下N是64)。

在十六进制中,我们有0x3b9aca00 << 40,产生0x3b9aca000000000000。减少此模块2 64 相当于截断64个低位以外的所有位,产生0x9aca000000000000,小数为11153727427136454656