4

I'm starting to program in C and I'm having a problem to understand some results I'm getting. I'll paste the code here:

#include <stdio.h>
unsigned int main(void)
{
    unsigned int x = 0;

    printf("%u\n",x-1);
    return 0;
}

The terminal is returning 4.294.967.295, and I'm not getting why. I know that this value is the max value of a unsigned int, but actually I was expecting some warning from the compiler that I would have to use a int type not an unsigned int because the result is negative. Anyway, can someone help me?

Toon Krijthe
  • 52,876
  • 38
  • 145
  • 202

7 Answers7

3

When you use an unsigned type all of the bits are used to represent non-negative values ( i.e., >= 0). Think of this as the values wrapping around, so when you decrement below the lower limit (0), you wrap around to the largest value (with 32 bits, 2^32 - 1).

Also, note you did not assign a negative value to variable x, you just provided an expression that subtracted 1 from it. I.e.,

x-1

vs

x = x - 1;

though whether you would have gotten a warning about this would probably depend on the compiler and the warning levels set.

Levon
  • 138,105
  • 33
  • 200
  • 191
1

It's the fixed number of bits (32), and two's complement that get you here.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171
  • 4
    Twos's complement is for signed numbers. These are unsigned binary representations without a sign bit. – uɐɪ Aug 10 '12 at 13:56
  • Yes, but the machine doesn't care. – Nikolai Fetissov Aug 10 '12 at 14:16
  • @nikolai; unsigned are defined to be arithmetic modulo 2^N. The machine *might* care under certain circumstances. But there's no concept of over/underflow for modulo arithmetic. Modulo 4, 3 + 1 is 0, and there's no overflow. Whereas with integers, adding 1 to a number can cause overflow. – Tom Tanner Aug 10 '12 at 14:21
1

unsigned int as it's name implies has no sign.

unsigned int values are represented as a 32 bit values, so when you subtract one it rolls over from 0x00000000 to 0xFFFFFFFF, that gives you the 4294967295 you are getting.

Bruno Ferreira
  • 942
  • 9
  • 22
1

The C Standard says that all unsigned arithmetic happens within the modulo 2^N range, where N is the number of bits in the type. Thus, substracting 1 from 0 in unsigned arithmetic does not result in -1, but in UINT_MAX.

Think of the unsigned values as a ring, where 0 is glued next to UINT_whatever. Regardless of whether you are adding, subtracting, shifting, multiplying, even negating, you'll never leave the ring. So you are perfectly allowed to do things like

 unsigned int x = -1;    /* Assigns UINT_MAX. */ 
Jens
  • 69,818
  • 15
  • 125
  • 179
0

Unsigned means that you have only positive values. Computers stores numbers as binary with some rules. When you do 0 - 1 you got maximum int value. You may read more about it here: http://en.wikipedia.org/wiki/Signed_number_representations

Marcin Zaluski
  • 687
  • 5
  • 10
0

Because unsigned int cannot store negative integers.

Please read up about ones-complement and twos-complex numbers.

What is happening that the top bit is being set along with the others and is then interpreted as a positive number.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
0

You don't get the error because the compiler can't know what will you do in future.

Nikola
  • 14,888
  • 21
  • 101
  • 165