表达式中移位和按位补码的反转优先级
Posted
技术标签:
【中文标题】表达式中移位和按位补码的反转优先级【英文标题】:Reverse precedence of shift and bitwise complement in an expression 【发布时间】:2017-10-15 06:00:41 【问题描述】:在这段代码中:
unsigned short int i = 3;
unsigned short int x = 30;
unsigned short int z = (~x) >> i;
在第三行,它似乎首先进行移位,然后是补码 (~),即使我使用括号也是如此。
但是,如果我将short
替换为long
,则不会出现奇怪的结果。
它发生在 Windows 和 Unix 中。这是为什么呢?
【问题讨论】:
请解释是什么让你这么认为。 你打印了中间结果 ((~x) , (x>>3), (~x)>>3, ~(x>>3) 吗?它们是什么?~
运算符是 not 否定的,没有人这样引用它。它是按位补码运算符。
您需要了解的是,补码和移位操作是在全尺寸整数上执行的,而不是短裤。然后将结果剪裁以适合短片。这就是为什么你没有得到你期望的结果。
非常感谢您的回答。你帮了大忙!
【参考方案1】:
它完全按照您指定的顺序执行操作。
但是,操作数不是无符号短整数。在执行操作之前,积分提升将 x
和 i
转换为良好的旧正则 signed 整数。引用 C 标准:
6.3.1 Arithmetic operands / paragraph 2
以下内容可以用在表达式中,只要是 int 或 unsigned 可以使用 int:
具有整数类型(int 或 unsigned int 除外)的对象或表达式,其整数转换等级小于或等于 int 和 unsigned int 的等级。如果一个 int 可以表示原始类型的所有值(受限制 通过宽度,对于位域),值被转换为 int; 否则,将其转换为无符号整数。
在您尝试过的机器上,无符号短裤可以紧贴有符号整数。
此外,有符号整数的右移具有实现定义的负值结果:
6.5.7 Bitwise shift operators / paragraph 5
E1 >> E2 的结果是 E1 右移 E2 位位置。如果 E1 有一个无符号类型,或者如果 E1 有一个有符号类型和一个非负数 值,结果的值是商的整数部分 E1 / 2E2 。 如果 E1 具有带符号类型和负值,则 结果值是实现定义的。
而~x
是一个负整数(它完全取决于有符号整数的值表示)。
以上所有因素更可能导致您在将其转换回无符号短整数时未获得预期结果。
【讨论】:
@IrisGaber - 我的荣幸以上是关于表达式中移位和按位补码的反转优先级的主要内容,如果未能解决你的问题,请参考以下文章