为什么在C中,对于无符号数据,右移必须是逻辑的?
这是来自计算机系统,程序员的观点
答案 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标准。小心!