移位运算符如何影响无符号数字

How does shift operators affect unsigned numbers

本文关键字:影响 无符号 数字 运算符 何影响      更新时间:2023-10-16

假设x是无符号的int

x << n等于x * 2n

我知道有符号整数也是如此。

x * 15等于x << 4 - x吗?

这个答案是针对 C 语言的。对于这个特定问题,C++规范似乎存在细微差异。

如果x是无符号的,并且n >= 0且小于x类型的值位数,则x << n确实等于将x乘以 2 的第 n 次方。

如果此计算溢出,则结果将模数减少为x加 1 类型的最大值。

如果x是签名的,它必须是非负数,结果不得溢出,否则您将获得未定义的行为。在 32 位体系结构上,未定义行为的常见情况如下:

unsigned x = 1 << 31;   /* undefined behavior: 1 is signed, 31 is too large */

正确的版本是:

unsigned x = 1U << 31;   /* correct on 32 bit architectures */

顺便说一下,自C++14以来,C++标准对这种情况有具体规定:

如果a << b的值在返回类型的无符号版本中可表示(然后将其转换为有符号:这使得创建INT_MIN作为1 << 31是合法的(,则 2 B 的值是乘以 2b,否则行为是未定义的。

关于你的第二个问题,x * 15等于x << 4 - x吗?

答案是否定的,因为x << 4 - x被解析为x << (4 - x).

如果你用括号括起来你的表达式,那么确实x * 15 == (x << 4) - x.

但请注意,对于有符号值,它不正确,因为中间结果x << 4可能会溢出较大的x值,而x * 15的结果不会溢出。