Why stores 255 in a char variable give its value -1 in C?

后端 未结 5 1125
夕颜
夕颜 2021-01-03 06:29

I am reading a C book, and there is a text the author mentioned:

\"if ch (a char variable) is a signed type, then storing 255 in the ch variable gives it the

相关标签:
5条回答
  • 2021-01-03 06:48

    You have classical explanation in others messages. I give you a rule:

    In a signed type with size n, presence of MSB set as 1, must interpreted as -2^(n-1).

    For this concrete question, assuming size of char is 8 bits length (1 bytes), 255 to binary is equal to:

    1*2^(7) +  
    1*2^(6) + 
    1*2^(5) + 
    1*2^(4) + 
    1*2^(3) + 
    1*2^(2) + 
    1*2^(1) + 
    1*2^(0) = 255
    
    255 equivalent to 1 1 1 1 1 1 1 1.
    

    For unsigned char, you get 255, but if you are dealing with char (same as signed char), MSB represents a negative magnitude:

    -1*2^(7) +  
    1*2^(6) + 
    1*2^(5) + 
    1*2^(4) + 
    1*2^(3) + 
    1*2^(2) + 
    1*2^(1) + 
    1*2^(0) = -1
    
    0 讨论(0)
  • 2021-01-03 06:53

    Assuming 8-bit chars, that is actually implementation-defined behaviour. The value 255 cannot be represented as a signed 8-bit integer.

    However, most implementations simply store the bit-pattern, which for 255 is 0xFF. With a two's-complement interpretation, as a signed 8-bit integer, that is the bit-pattern of -1. On a rarer ones'-complement architecture, that would be the bit pattern of negative zero or a trap representation, with sign-and-magnitude, it would be -127.

    If either of the two assumptions (signedness and 8-bit chars) doesn't hold, the value will be¹ 255, since 255 is representable as an unsigned 8-bit integer or as a signed (or unsigned) integer with more than 8 bits.

    ¹ The standard guarantees that CHAR_BIT is at least 8, it may be greater.

    0 讨论(0)
  • 2021-01-03 06:54

    Try it in decimal. Suppose we can only have 3 digits. So our unsigned range is 0 - 999.

    Let's see if 999 can actually behave as -1 (signed):

    42 + 999 = 1041
    

    Because we can only have 3 digits, we drop the highest order digit (the carry):

    041 = 42 - 1
    

    This is a general rule that applies to any number base.

    0 讨论(0)
  • 2021-01-03 06:54

    That's how two's complement works. Read all about it here.

    0 讨论(0)
  • 2021-01-03 06:59

    That is not guaranteed behavior. To quote ANSI/ISO/IEC 9899:1999 §6.3.1.3 (converting between signed and unsigned integers) clause 3:

    Otherwise, the new type is signed and the value cannot be represented in it;
    either the result is implementation-defined or an implementation-defined signal
    is raised.
    

    I'll leave the bitwise/2's complement explanations to the other answers, but standards-compliant signed chars aren't even guaranteed to be too small to hold 255; they might work just fine (giving the value 255.)

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