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.
- Modern C, Jens Gustedt
Question: What's wrong with "two values evaluating to zero" according to the last statement (in bold)?
CodePudding user response:
What's wrong with "two values evaluating to zero" according to the last statement (in bold)?
Example: strings
When char
is signed, what is wrong with this code if integer encoding is not 2's complement?
size_t my_strlen(const char *s) {
const char *t = s;
while (*t) {
t ;
}
return t - s;
}
while (*t)
stops on both 0 and -0, when it should stop only on 0.
String handling
<string.h>
For all functions in this subclause, each character shall be interpreted as if it had the typeunsigned char
(and therefore every possible object representation is valid and has a different value). C17dr 7.24.1 3
Should have used
const unsigned char *t = s;
. With 2's complement, make no difference either way.
Basic problem is that there are times when code should distinguish 0 from -0, but common code only look at the value, and not the sign of an signed integer when it is 0.
C2x is expected to require 2's complement.
Corner benefits of non-2's complement: Symmetric positive and negative ranges.
abs(i)
value for all i
. -i
valid for all i
. -1/x
is never a problem for non-zero x
.