Unsigned and Signed int and printf

前端 未结 2 1016
感动是毒
感动是毒 2020-12-10 23:36

I understand that I am assigning signed int a value that is larger than what it can handle. Also I should be using %d for signed and %u for unsigne

相关标签:
2条回答
  • 2020-12-10 23:56

    That is why %u for signed prints 4294967295 by ignoring -ve leftmost bit. When used %d for signed int, it uses left most bit as -ve flag and prints -1.

    In the case of unsigned, the "leftmost" or most significant bit is not ignored, and is not negative; rather it has a place value of 231.

    In the negative case, the sign bit is not a flag; instead it is a bit with a place value of -231.

    In both cases the value of the integer is equal to the sum of the place values of all the binary digits (bits) set to 1.

    The encoding of signed values in this way is known as two's complement. It is not the only possible encoding; what you described is known as sign and magnitude for example, and one's complement is another possibility. However, these alternative encodings are seldom encountered in practice, not least because two's complement is how arithmetic works on modern hardware in all but perhaps the most arcane architectures.

    0 讨论(0)
  • 2020-12-11 00:05

    There are a few things going on here let's start out by saying that using the incorrect format specifier to printf is undefined behavior which means the results of your program are unpredictable, what actually happens will depends on many factors including your compiler, architecture, optimization level, etc...

    For signed/unsigned conversions, that is defined by the respective standards, both C and C++ make it implementation defined behavior to convert a value that is larger than be stored in a signed integer type, from the C++ draft standard:

    If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

    for example gcc chooses to use the same convention as unsigned:

    For conversion to a type of width N, the value is reduced modulo 2^N to be within range of the type; no signal is raised.

    When you assign -1 to an unsigned value in both C and C++ the result will always be the maximum unsigned value of the type, from the draft C++ standard:

    If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]

    The wording from C99 is easier to digest:

    Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

    So we have the following:

    -1 + (UNSIGNED_MAX + 1)
    

    the result of which is UNSIGNED_MAX

    As for printf and incorrect format specifier we can see form the draft C99 standard section 7.19.6.1 The fprintf function says:

    If a conversion specification is invalid, the behavior is undefined.248) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

    fprintf covers printf with respect to format specifiers and C++ falls back in C with respect to printf.

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