这是我的代码:
#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
进行编译。
答案 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
。