我有以下程序:
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
这是为什么?
答案 0 :(得分:5)
如果将这些整数转换为带符号的2的补码二进制,则可以了解原因:
241294423792285589以二进制形式是
0000001101011001010000000000000000000000011010111111011110010101
向左移动63个点将导致最右边的1
以最左边的二进制数结尾:
1000000000000000000000000000000000000000000000000000000000000000
2的补码二进制为-9223372036854775808。
您可以在线找到二进制<->十进制转换器(例如https://www.rapidtables.com/convert/number/decimal-to-binary.html),可以使这一点更加清楚。
或者您甚至可以尝试使用以下移位计算器:https://bit-calculator.com/bit-shift-calculator
答案 1 :(得分:4)
您的班次表达式具有未定义的行为。您可以从这种转变中毫无意义地期待任何价值。
在C中,有符号的E1 << E2
左移E1
的行为由6.5.7 / 4描述
如果E1具有带符号的类型且非负值,并且E1×2 E2 在结果类型中可表示,则为结果值;否则,行为是不确定的。
答案 2 :(得分:0)
问题是您将一个奇数(设置了最低有效位的数字)左移了63位(在64位字中)。您获得的价值是
0b1000_0000_0000_0000_...._0000
或
0x8000000000000000
(以二进制补码)是您在问题中发布的号码。
无论如何,将63移位会放置一个带符号的64位数字是不确定的行为,因此这意味着您可以接收到任何东西...如果出现巨大的负数,则为空。