gpt4 book ai didi

c++ - c/c++ 左移无符号与有符号

转载 作者:可可西里 更新时间:2023-11-01 16:27:24 27 4
gpt4 key购买 nike

我有这个代码。

#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 bridge 架构上。

第一个结果有道理,但我不明白第二个数字是从哪里来的。 1 表示为 4byte int signed or unsigned is

00000000000000000000000000000001

当你将它向左移动 31 次时,你会得到

10000000000000000000000000000000

没有?我知道左移正数本质上是 2^k,其中 k 是你移动它的次数,假设它仍然在边界内。为什么我得到这么奇怪的数字?

最佳答案

想必您对为什么会这样感兴趣:unsigned long int uwantsum = 1 << 31;产生一个“奇怪”的值。

问题很简单:1 是一个普通的 int , 所以转移是在一个普通的 int 上完成的, 只有在它完成后,结果才会转换为 unsigned long .

然而,在这种情况下,1<<31溢出 32 位有符号整数的范围,因此结果为未定义的1。转换为无符号后,结果仍未定义。

也就是说,在大多数典型情况下,可能发生的情况是 1<<31将给出 10000000000000000000000000000000 的位模式.当被视为带符号的 2 的补码2 数时,它是 -2147483648。由于这是负数,当它转换为 64 位类型时,它将被符号扩展,因此前 32 位将填充第 31 位中内容的拷贝。这给出:1111111111111111111111111111111110000000000000000000000000000000 (33 个 1 位后跟 31 个 0 位)。

如果我们随后将其视为无符号 64 位数字,我们将得到 18446744071562067968。


  1. §5.8/2:<支持>

    The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

  2. 理论上,计算机可以对带符号的数字使用 1 的补码或带符号的大小,但 2 的补码目前比这两者都更常见。如果它确实使用了其中之一,我们预计最终结果会有所不同。

关于c++ - c/c++ 左移无符号与有符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22904670/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com