Unsigned and Signed Values in C (Output)

前端 未结 5 1180
余生分开走
余生分开走 2020-12-15 01:21
signed int x = -5;
unsigned int y = x;

What is the value of y? How is this so?

5条回答
  •  暖寄归人
    2020-12-15 01:55

    Signed values are typically stored as something called two's complement:

    Two's complement numbers are a way to encode negative numbers into ordinary binary, such that addition still works. Adding -1 + 1 should equal 0, but ordinary addition gives the result of 2 or -2 unless the operation takes special notice of the sign bit and performs a subtraction instead. Two's complement results in the correct sum without this extra step.

    This means that the actual representation of the numbers -5 and 4294967291 in memory (for a 32 bit word) are identical, e.g: 0xFFFFFFFB or 0b11111111111111111111111111111011. So when you do:

    unsigned int y = x;
    

    The contents of x is copied verbatim, i.e. bitwise to y. This means that if you inspect the raw values in memory of x and y they will be identical. However if you do:

    unsigned long long y1 = x;
    

    the value of x will be sign-extended before being converted to an unsigned long long. In the common case when long long is 64 bits this means that y1 equals 0xFFFFFFFFFFFFFFFB.

    It's important to note what happens when casting to a larger type. A signed value that is cast to a larger signed value will be sign-extended. This will not happen if the source value is unsigned, e.g.:

    unsigned int z = y + 5;
    long long z1 = (long long)x + 5; // sign extended since x is signed
    long long z2 = (long long)y + 5; // not sign extended since y is unsigned
    

    z and z1 will equal 0 but z2 will not. This can be remedied by casting the value to signed before expanding it:

    long long z3 = (long long)(signed int)y + 5;
    

    or analogically if you don't want the sign extension to occur:

    long long z4 = (long long)(unsigned int)x;
    

提交回复
热议问题