我有这个代码。
#include <iostream>
int main()
{
unsigned long int i = 1U << 31;
std::cout << i << std::endl;
unsigned long int uwantsum = 1 << 31;
std::cout << uwantsum << std::endl;
return 0;
}
它打印出来。
2147483648
18446744071562067968
在 Arch Linux 64 位、gcc、ivy 桥架构上。
第一个结果是有道理的,但我不明白第二个数字来自哪里。 1 表示为 4byte int 有符号或无符号
00000000000000000000000000000001
当你向左移动 31 次时,你最终会得到
10000000000000000000000000000000
不?我知道向左移动正数本质上是 2^k,其中 k 是移动它的次数,假设它仍然在范围内。为什么我会得到这么奇怪的数字?
想必您对为什么会这样感兴趣:unsigned long int uwantsum = 1 << 31;
产生一个“奇怪”的值。
问题很简单: 1 是一个普通的int
,所以移位是在一个简单的int
,只有完成后,结果才会转换为unsigned long
.
In this case, however, 1<<31
overflows the range of a 32-bit signed int, so the result is undefined1. After conversion to unsigned, the result remains undefined.
That said, in most typical cases, what's likely to happen is that 1<<31
will give a bit pattern of 10000000000000000000000000000000
. When viewed as a signed 2's complement2 number, this is -2147483648. Since that's negative, when it's converted to a 64-bit type, it'll be sign extended, so the top 32 bits will be filled with copies of what's in bit 31. That gives: 1111111111111111111111111111111110000000000000000000000000000000
(33 1-bits followed by 31 0-bits).
如果我们将其视为无符号 64 位数字,我们将得到 18446744071562067968。
- §5.8/2:
E1 否则,行为是未定义的.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)