【发布时间】:2012-06-25 21:14:48
【问题描述】:
我知道 -127 的二进制表示是 10000001(补码)。
谁能告诉我为什么我将它右移 1 位,然后我得到 11000000 ?
(-127) = 10000001
(-127>>1) = 11000000 ???
谢谢。
【问题讨论】:
-
思考:“符号填充移位”
标签: java algorithm computer-science
我知道 -127 的二进制表示是 10000001(补码)。
谁能告诉我为什么我将它右移 1 位,然后我得到 11000000 ?
(-127) = 10000001
(-127>>1) = 11000000 ???
谢谢。
【问题讨论】:
标签: java algorithm computer-science
如果您的编程语言进行符号扩展右移(如 Java 所做的那样),那么最左边的 1 来自扩展符号。也就是说,由于最高位设置为原始数字,因此每次移位的结果中都保持设置(因此移位超过 1 时,最高位中的所有 1 对应于完成的移位次数)。
这取决于语言 - IIRC C 和 C++ 在右移时对有符号值进行符号扩展,而不是对无符号值进行符号扩展。 Java 有一个特殊的 >>> 运算符,可以在不扩展的情况下进行移位(在 Java 中,所有数字原始值都是有符号的,包括误导性命名的字节)。
【讨论】:
signed int 时进行符号扩展。这使得 C/C++ char 的默认符号 unspecified 有点烦人......
在某些语言中,右移会填充最高有效位中的任何内容(在本例中为 1)。这是为了使符号在移动负数时不会改变,如果不这样做,它会变成正数。
【讨论】:
-127 作为 WORD(2 个字节)是 1111111110000001。如果您将其右移 1 位,并将其表示为单个字节,则结果为 11000000 这可能就是您所看到的。
【讨论】:
因为,如果您将 -127(编码为 10000001)的 -127(two's-complement)除以 2 并向下舍入(朝向 -infinity,而不是朝向零),您会得到 -64(编码为 11000000 的二进制补码)。
按位,原因是:当右移有符号值时,您执行sign-extension - 而不是移入零,而是复制最高有效位。当使用二进制补码有符号数时,这可以确保得到正确的结果,如上所述。
汇编语言(以及它们编码的机器语言)通常具有用于无符号和有符号右移操作(也称为“逻辑右移”与“算术右移”)的单独指令;和编译语言通常在分别移动无符号和有符号值时选择适当的指令。
【讨论】:
它是符号扩展,因此右移的负数仍然是负数。
【讨论】: