How does std::cout print negative zero in a ones-complement system?

前端 未结 4 1503
遇见更好的自我
遇见更好的自我 2021-01-17 09:34

On a ones-complement platform, what would the following code print?

#include 

int main() {
    int i = 1, j = -1;

    std::cout << i+         


        
相关标签:
4条回答
  • 2021-01-17 10:12

    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;
    }
    
    0 讨论(0)
  • 2021-01-17 10:14

    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.

    0 讨论(0)
  • 2021-01-17 10:19

    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).

    0 讨论(0)
  • 2021-01-17 10:23

    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.

    0 讨论(0)
提交回复
热议问题