On a ones-complement platform, what would the following code print?
#include
int main() {
int i = 1, j = -1;
std::cout << i+
First of all, just to clarify thing, crafting a negative zero using bitwise operations and then using the resulting value is not portable. That said, nothing specifies in the documentation of fprintf
(thus, of std::basic_ostream::operator<<(int)
) whether the sign bit in the representation of int corresponds to a padding bit in the representation of unsigned
or an actual value bit.
As a conclusion, this is unspecified behaviour.
#include <iostream>
int main() {
std::cout << ~0 << std::endl;
return 0;
}
Looking through the glibc source code, I found these lines in vfprintf.c:
532 is_negative = signed_number < 0; \
533 number.word = is_negative ? (- signed_number) : signed_number; \
534 \
535 goto LABEL (number); \
...
683 if (is_negative) \
684 outchar (L_('-')); \
So it would appear that the condition is signed_number < 0
, which would return false for a -0
.
as @Ysc mentioned, nothing in the documentation gives any specification to printing -0
, so a different implementation of libc (on a ones-compliment) platform may yield a different result.
Indeed adding n
to -n
should give you a negative zero. But the generation of -0 doesn't happen in practice since 1's complement addition uses a technique called a complementing subtractor (the second argument is complemented and subtracted from the first).
(The idiomatic way of getting a signed floating point zero doesn't apply here since you can't divide an integer by zero).
If we view the theoretical point of the one's complement. Since the zero is defined as (+/-)0 there will be two binary values for 0 if we have 4 Bit values the zero will be 0000 (+0) and 1111 (-0). As a result of this you always have to do a correction if an operation, addition or substraction, has a zero-crossing operation in it.
So for example if we do the following operation -2+6=4
the result will be calculated as followed:
1101 (-2)
+ 0110 (6)
------
1100 (add carry)
======
0011 (+3)
As you can see in the Bit operation the result is incorrect and is only the incomplete result. In this case we have to add a +1 to the value to get the correct result. To identify if the +1 has to be added we have to take a look at the add carry result. If the most left numer 1100 is a ONE than we have to add +1 to the result to get the correct result.
If we have a look at your example:
0001 (+1)
+ 1110 (-1)
------
0000 (add carry)
======
1111 (-0)
We see that the result will be -0 and this will be the final result because the left add carry bit is 0.