【发布时间】:2022-01-18 13:18:03
【问题描述】:
C 允许三种不同的符号表示:
符号和大小
反码
补码
前两个现在可能只具有历史或异国情调:对于符号和幅度,幅度被视为正值,符号位只是指定有一个减号。反码取相应的正值, 补全所有位。 这两种表示都有一个缺点,即两个值的计算结果为 0:有一个正 0 和一个负 0。
来源:Modern C,Jens Gustedt
问题:根据最后一条语句(粗体),“两个值计算为零”有什么问题?
【问题讨论】:
-
对于有符号整数(以及浮点数),最左边的位保留给符号位。所以,
1000......0000和0000......0000都为零,但前者的符号位打开,意思是“负数”。 -
一个 8 位整数有 256 个可能的数字。如果你有两个数字,你只有 255 个可能的数字。例如,
-128到127用于 2s 补码,-127到127用于另一个。 -
怎么了……?好吧,除了您“浪费”一种可能的表示(微不足道)这一事实之外,如果两个零值具有不同的表示,代码可能会在位比较中失败。
-
或许问@Jens Gustedt?
-
@AdrianMole you're 'wasting' one possible representation 参数也适用于常见的浮点。
-INT_MAX != INT_MIN也有 2 的补码问题。我不认为非 2 的补码是错误的,因为多年来它输给了 2 的补码作为较弱的方法。