为什么SCHAR_MIN在C99中定义为-127?

时间:2011-11-04 13:39:36

标签: c char language-lawyer c99

C99的§5.2.4.2.1将SCHAR_MIN定义为-127,将SCHAR_MAX定义为127. 8位有符号整数的范围不应该是-128到+127吗?

我的编译器的limits.h将SCHAR_MIN定义为(-1 << ((CHAR_BIT)-1)),如果CHAR_BIT为8,则为-128。

是否有任何理由为SCHAR_MIN定义-127而不是-128?

1 个答案:

答案 0 :(得分:25)

它实际上并未将SCHAR_MIN定义为-127,它将已签名字符的最小范围定义为-127..127。

这样做是因为它必须能够处理有符号数的其他两种编码方案,即那些是补码和符号/幅度的编码方案。这两个都有一个正的负零,偷走你在二进制中找到的-128。

ISO C(C99),第6.2.6.2/2部分指出,实现必须为签名的整数数据类型选择以下三种不同表示之一:

  • 两个补充;
  • 的补充;或
  • 符号/幅值

这两个补充实现远远超过其他实现,但其他存在。

在所有这些表示中,正数是相同的,唯一的区别是负数。

要获得正数的否定表示,您:

  • 反转所有位,然后添加一个用于二进制补码。
  • 将所有位反转为“补码”。
  • 仅反转符号/符号的符号位。

对于5和0,您可以在下表中看到:

number | two's complement    | ones' complement    | sign/magnitude
=======|=====================|=====================|====================
     5 | 0000 0000 0000 0101 | 0000 0000 0000 0101 | 0000 0000 0000 0101
    -5 | 1111 1111 1111 1011 | 1111 1111 1111 1010 | 1000 0000 0000 0101
       |                     |                     |
     0 | 0000 0000 0000 0000 | 0000 0000 0000 0000 | 0000 0000 0000 0000
    -0 | 0000 0000 0000 0000 | 1111 1111 1111 1111 | 1000 0000 0000 0000
           (no difference)        (both of these have distinct +/-0)