为什么在C中,对于无符号数据,右移必须是合乎逻辑的?

时间:2015-05-23 23:54:59

标签: c

为什么在C中,对于无符号数据,右移必须是逻辑的?

这是来自计算机系统,程序员的观点

4 个答案:

答案 0 :(得分:3)

在无符号类型上,逻辑移位和算术移位是相同的。

答案 1 :(得分:1)

因为SAR(算术移位)根据移位前的前一个MSB位填充最高有效位,所以有效地将其作为符号位处理并保留正确的符号,而SHR(逻辑移位)只是清除它。

对于设置了MSB的无符号值,如果向右移动以将值除以2,则需要从MSB填充零,否则结果将毫无意义。我假设这是作者的意思,尽管可以更好地解释。

link

  

移位算术权(SAR)和移位逻辑权(SHR)   指令将目标操作数的位移到右侧   (朝向不太重要的位置)。对于每个轮班计数,   目标操作数的最低有效位被移入   CF标志,最高有效位设置或清除   取决于指令类型。 SHR指令清除最多   重要的一点(参见IA-32英特尔架构中的图7-8)   软件开发人员手册,第1卷); SAR指令设置或   清除最重要的位以对应符号(大多数   目标操作数中原始值的有效位。在   效果,SAR指令填充空位位置的移位   带有未移位值的符号的值(参见图7-9)   IA-32英特尔架构软件开发人员手册,第1卷。

     

SAR和SHR指令可用于执行有符号或无符号   目标操作数的除法分别为2的幂   例如,使用SAR指令将有符号整数1位移位到   右边将值除以2。

顺便说一句,这是汇编中的一个问题,这两个操作是分开的。在c中,使用shift运算符应该根据值类型编译为适当的操作类型(不是签名)

答案 2 :(得分:0)

它必须是合乎逻辑的,因为您希望所有位都被右移。

示例:

1111>> 2应该成为0011。 这是通过逻辑转换完成的。

算术转换会给你1111>> 2 = 1001。

您可以将其视为一种sign extension

答案 3 :(得分:0)

移位运算符有两种常见类型:算术运算符和逻辑运算符。逻辑移位运算符从一端丢弃位,在另一端填充零位。算术移位在一端丢弃位,并在另一端填充已经在该端的位的副本。

通常,逻辑移位可在两个方向上使用,但算术移位可从最高有效位到最低有效位;即从左到右。 (当然,我所知道的HLL语言就是这种情况。它可能不是普遍适用的;例如在所有ISA的指令集级别。)

在Java 1 中,>>是算术(符号扩展)移位,>>>是逻辑(零扩展)移位。

签名示例:

  00000010 >> 1   becomes 00000001  ( 2 becomes 1 )
  10000000 >> 1   becomes 11000000  ( -128 becomes -64 )

算术移位的目的是处理位表示带符号(2的补码)整数的值。例如,signed_value >> 1相当于将值除以2.这是有效的,因为2的补码值的最高有效位(在左端)对于负值是1而对于非负值是0

但是,您询问的是无符号值。对于这样的值,最高有效位不是符号位,因此除以2(来自上面的示例)执行为unsigned_value >>> 1。注意:这是逻辑移位运算符。

如果你写了unsigned_value >> 1,你会得到一个不是无符号值除以2的结果的答案;即错误的答案......对于这个问题。

无符号示例:

  00000010 >>> 1   becomes 00000001  ( 2 becomes 1 )
  10000000 >>> 1   becomes 01000000  ( 128 becomes 64 )
  10000000 >> 1    becomes 11000000  ( 128 becomes 196 ???? )

1 - 在C ++中>>是一个算术移位,如果第一个操作数类型是有符号的,逻辑移位是无符号的。在C中,签名类型上>>的含义是“实现定义”...根据2007 C标准。小心!