我有以下程序:
int main()
{
int64_t a = 241294423792285589;
printf("a = %lld, a << 63 = %lld", a, a << 63);
return 0;
}
我期望a << 63
为0,但它打印出来:
a = 241294423792285589, a << 63 = -9223372036854775808
为什么这是?
如果将这些整数转换为签名2的补充二进制文件,您可以看到为什么:
241294423792285589在二进制中
0000001101011001010000000000000000000000011010111111011110010101
将其左移63个斑点移动将导致最右边的1
最终以最左侧的二进制数字结束:
1000000000000000000000000000000000000000000000000000000000000000
在2的补充二进制中,是-9223372036854775808。
您可以在线找到二进制&lt; ->十进制转换器(例如:https://www.rapidtables.com/convert/number/decimal/decimal/decimal-to-binary.html(可以帮助您更加清楚这一点。
或者您甚至可以尝试此BITSHIFT计算器:https://bit-calculator.com/bit-shift-calculator
您的移位表达式具有未定义的行为。您没有任何价值从这种转变中有意义的期望。
在左移E1 << E2
的C行为中,用于签名的E1
由6.5.7/4
如果E1具有签名类型和非负值,并且E1×2 E2 在结果类型中表示可表示,则是结果值;否则,行为是不确定的。
问题在于,您剩下一个奇数数(一个数字最少的位置设置的数字(,左侧的63个位置为64位单词。您获得的价值是
0b1000_0000_0000_0000_...._0000
或
0x8000000000000000
(在两个补充中(是您在问题中发布的数字。
无论如何,转移63位a 签名的64位号是未定义的行为,因此这意味着您可以完全收到任何东西...事件,巨大的负数。