1
#include<stdio.h>
int main(void)
{ 
  signed int a=-1;
  unsigned int b=1;
  int c= a+b;
  printf("%d\n",c);

  return 0;
  }

According to the rule of Implicit type conversion, if one operand is unsigned int,the other will be converted to unsigned int and the result will be unsigned int in a binary operation. so here as b is unsigned int, a should be type casted to unsigned int.As unsigned int is always +ve , so the value of a will be 1.so c=1+1=2.But the output is 0.How ?

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
Parikshita
  • 1,297
  • 5
  • 15
  • 23
  • I believe this is implementation-defined (or undefined?) behaviour you are experiencing. – strager Oct 07 '10 at 18:24
  • @strager: yes, the behaviour of the assignment to `c` is implementation-defined. 6.3.1.3/3: "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." – Steve Jessop Oct 07 '10 at 18:55
  • 4
    You're both wrong. The relevant conversion is from signed to unsigned, not unsigned to signed, and the behavior is well-defined. `-1` is reduced modulo `UINT_MAX+1`, resulting in `UINT_MAX`, and adding 1 to that again results in reduction modulo `UINT_MAX+1` and thus 0. Converting 0 back to a signed type is then well-defined. – R.. GitHub STOP HELPING ICE Oct 07 '10 at 18:59
  • @R. True, with these values it's defined. For some reason [Edit: I figured out the reason - because Parixit offered a second example in a comment] I was thinking of the general case of storing the result of unsigned arithmetic in a signed value. – Steve Jessop Oct 07 '10 at 19:06

3 Answers3

16

-1, when cast to unsigned will become the largest possible value for that type -- e.g. with a 32-bit unsigned, it'll be 4,294,967,295. When you add 1 to that, the value "wraps around" to 0.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

"a should be type casted to unsigned int. As unsigned int is always +ve , so the value of a will be 1."

Correct up to "will be", but not thereafter ;-)

The result of converting a signed integer to unsigned is specified in the standard, 6.3.1.3/2:

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

In other words, the negative value is converted to unsigned by taking its value modulo some power of 2, not by flipping the sign.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
  • No, because -1 is not representable as an unsigned int, so it can't be the result of converting anything to unsigned int. There's a footnote in the standard saying that the "addition" or "subtraction" refers to the actual mathematical numbers involved, not to the `+` or `-` operators of any particular C type. The same applies to my use of "modulo" - I mean the mathematical operation, resulting in a value in the range `[0,UINT_MAX]`. I don't mean the signed `%` operator. – Steve Jessop Oct 07 '10 at 19:44
  • That said, as a mathematician by education, I do personally sometimes think of unsigned values as being abstract members of the ring modulo `UINT_MAX`. In which case, yes, the result of reducing -1 modulo `UINT_MAX+1` is still -1, but in a model where -1 is equal to `UINT_MAX`. It's probably not wise to make this your mental model of unsigned integers, though, because the model fails to describe certain C operations such as division. – Steve Jessop Oct 07 '10 at 19:47
-1

Modern machines mostly uses two's complement representation for negative numbers. When two numbers are added, if any of them is negative, it will be first converted to two's complement representation. then these two numbers will be added. So computers usually performs 1 - 1 as 1 + two's complement of (-1). This results to 0.

For 1 - 2, it is 1 + two's complement(-2). Check this program, same number, different representation:

int main()
{
    signed int a = 1;
    unsigned int b = -2;

    int c = a+b;

    printf("%d\n%u\n", c, c);

    return 0;
}

Please read about two's complement representation. You'll need that to become a programmer.

Donotalo
  • 12,748
  • 25
  • 83
  • 121
  • The behaviour of the addition has nothing to do with two's complement representation. It would be the same on a one's complement machine, right up to the point where the result is assigned to `c` (which is implementation-defined, as strager says). – Steve Jessop Oct 07 '10 at 18:57
  • -1 twos complement is irrelevant to OP's question, which has the same behavior on **any** C implementation. Your new example relies in implementation-specific behavior common to twos complement implementations. – R.. GitHub STOP HELPING ICE Oct 07 '10 at 19:01
  • my intention was to make the OP aware of most common implementation. sorry i should've noted it in original answer. – Donotalo Oct 07 '10 at 19:56