以下是什么意思。 C 语言中有符号类型的二进制表示?

What does the following mean wrt. binary representations of signed types in C language?

C allows three different sign representations:

  • Sign and magnitude

  • Ones’ complement

  • Two’s complement

The first two nowadays probably only have historical or exotic relevance: for sign and magnitude, the magnitude is taken as positive values, and the sign bit simply specifies that there is a minus sign. Ones’ complement takes the corresponding positive value and complements all bits. Both representations have the disadvantage that two values evaluate to 0: there is a positive and a negative 0.

资料来源:现代 C,Jens Gustedt

问题:根据最后一条语句(粗体),“两个值的计算结果为零”有什么问题?

What's wrong with "two values evaluating to zero" according to the last statement (in bold)?

示例:字符串

char有符号时,如果整数编码不是2的补码,这段代码有什么问题?

size_t my_strlen(const char *s) {
  const char *t = s;
  while (*t) {
    t++;
  }
  return t - s;
} 

while (*t) 在 +0 和 -0 上都停止,而它应该只在 +0 上停止。

字符串处理 <string.h> 对于本子条款中的所有函数,每个字符都应被解释为好像它具有 unsigned char 类型(因此每个可能的对象表示是有效的并且具有不同的值)。 C17dr 7.24.1 3

应该用 const unsigned char *t = s;。使用 2 的补码,无论哪种方式都没有区别。

基本问题是有时代码应该区分 +0 和 -0,但普通代码只看 value,而不是 [=40] 的符号=]有符号整数,当它为0时。


C2x 预计需要 2 的补码。

非 2 补码的优势对称 正负范围。 abs(i) 所有 i 的值。 -i 对所有 i 有效。 -1/x 对于非零 x.

永远不是问题