以下是什么意思。 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
.
永远不是问题
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
.