6

My little program:

#include <stdio.h>

int main() {
    signed char c = -128;
    c = -c;
    printf("%d", c);
    return 0;
}

print:

-128

Is minus (-) operator portable across CPU?

gavenkoa
  • 45,285
  • 19
  • 251
  • 303

3 Answers3

9

The operand of the unary minus first undergoes standard promitions, so it is of type int, which can represent the value -128. The result of the operation is the value 128, also of type int. The conversion from int to signed char, being a narrowing of signed types, is implementation-defined.

(Your implementation seems to do a simple wrap-around: 125, 126, 127, -128, -127, ...)

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • Does ANSI C convert primitive types to **int** before performing arithmetical operations? This is true for Java (as states Java lang spec), but is this true for C? – gavenkoa Jul 04 '13 at 12:20
  • @gavenkoa May be your answer: [C 2011 (n1570) 6.3.1.8 (“Usual arithmetic conversions”) 1 states that the integer promotions are performed before considering whether the types are the same:](http://stackoverflow.com/questions/12841278/char-and-the-usual-arithmetic-conversion-rules) – Grijesh Chauhan Jul 04 '13 at 12:26
  • @gavenkoa: Loosely speaking, everything that's "smaller" than an `int` is promoted to `int` during arithmetic operations. The result is then assigned back to the left-hand side. – Kerrek SB Jul 04 '13 at 12:27
  • 3
    @gavenkoa: Types that have a lower conversion rank than `int` are promoted to `int`, unless `int` cannot represent all the values of the original type, in which case they are promoted to `unsigned int`. – caf Jul 04 '13 at 12:28
4

Note: -128 in 2's complement is 1000 0000 (in one byte) and 128 is also 1000 0000 . If you do char c = 128 and print it it will be -128 because of the following reason:

A char variable = 128 value stores in memory as follows.

MSB
+----+----+----+---+---+---+---+---+
|  1 |  0 | 0  | 0 | 0 | 0 | 0 | 0 |   
+----+----+----+---+---+---+---+---+
   7    6   5    4   3   2   1   0  

Now,

  1. this value will be interpreted as negative value because MSB is 1,
  2. to print magnitude of this -ve number 2's complement needed, that is also 128 in one byte so output is: -128

    2's complement:

      1000 0000
    
      0111 1111  1's complement 
    + 0000 0001 
     -----------
      1000 0000  2's complement   
    
     Magnitude = 128 
     So in one byte 128 == -128
    
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
1

because a byte(char) can't hold 128

-128 = 0x80

what neg do is reverse it and plus 1

-(-128) = (~0x80) + 1 = 0x7F + 1 = 0x80

daha, you got 0x80 again

Zang MingJie
  • 5,164
  • 1
  • 14
  • 27