21

What will the unsigned int contain when I overflow it? To be specific, I want to do a multiplication with two unsigned ints: what will be in the unsigned int after the multiplication is finished?

unsigned int someint = 253473829*13482018273;
GILGAMESH
  • 1,816
  • 3
  • 23
  • 33
  • This seems to be a duplicate of http://stackoverflow.com/questions/199333/best-way-to-detect-integer-overflow-in-c-c – Niklas B. Feb 08 '12 at 13:12
  • 2
    Why not try it and see what you get? In general, when an unsigned int overflows, it rolls over to zero. So `UINT_MAX + 5` rolls over and becomes 4. – Some programmer dude Feb 08 '12 at 13:15
  • It would be the difference between the max uint value and the value of what would have been the overflow value. Lets make it simple. Lets say the max uint is 5. You want to add 2 * 4 so this makes the final value 3 instead of 8. – Security Hound Feb 08 '12 at 13:17
  • http://stackoverflow.com/questions/988588/is-using-unsigned-integer-overflow-good-practice – Stefan Birladeanu Feb 08 '12 at 13:17

3 Answers3

29

unsigned numbers can't overflow, but instead wrap around using the properties of modulo.

For instance, when unsigned int is 32 bits, the result would be: (a * b) mod 2^32.


As CharlesBailey pointed out, 253473829*13482018273 may use signed multiplication before being converted, and so you should be explicit about unsigned before the multiplication:

unsigned int someint = 253473829U * 13482018273U;
Pubby
  • 51,882
  • 13
  • 139
  • 180
  • is that a part of a standard? – ev-br Feb 08 '12 at 13:15
  • 2
    @Zhenya Yes, in both C and C++. – Pubby Feb 08 '12 at 13:17
  • @Zhenya - Does it matter? The answer is 100% correct. Its a more technical way of saying UINT_MAX + 5 is 4. This likely would remain true in both .NET languages and Java. At least in the case of .NET NaN is limited to types like double where the value ( most of the time ) is not represented exactly. – Security Hound Feb 08 '12 at 13:18
  • The same happens with other built-in data types , right? , Thanks – Mr.Anubis Feb 08 '12 at 13:23
  • 2
    @Ramhound: Of course it matters. If the standard didn't define this behaviour (like it doesn't for signed integer types), then you couldn't rely on it. – Mike Seymour Feb 08 '12 at 13:25
  • 1
    @Mr.Anubis: No, only unsigned integer types. Signed and floating point overflows give undefined behaviour. – Mike Seymour Feb 08 '12 at 13:26
  • 2
    This answer is not necessarily relevant. Depending on the compiler limits, the expression `253473829*13482018273` may use signed integer arithmetic which may overflow _before_ the result is converted to `unsigned int`. – CB Bailey Feb 08 '12 at 13:30
  • 1
    @CharlesBailey: The question asks about multiplying two `unsigned int`s, even if the example code shows something else. – Mike Seymour Feb 08 '12 at 13:34
  • @MikeSeymour you mean all signed types and including floating types, and excluding all unsigned types, right?, Thanks – Mr.Anubis Feb 08 '12 at 15:13
  • @Mr.Anubis: Yes; the behaviour is defined for unsigned integer types only. – Mike Seymour Feb 08 '12 at 15:21
  • Except with regard to promotion rules, unsigned values mostly do not behave as numbers, but rather members of an algebraic ring (typically Z256, Z65536, Z4294967296, or Z18446744073709551616). X-Y is the value which, when added to Y, will yield X. Some promotion rules are correct when applied to members of an algebraic ring (e.g. adding an unsigned value to an int which is no larger correctly moves around the ring), though some are not. In a new language design, it might be helpful to have separate types for numbers and algebraic rings; both have their uses, independent of signedness. – supercat Jan 10 '14 at 23:55
7

Unsigned integer overflow, unlike its signed counterpart, exhibits well-defined behaviour.

Values basically "wrap" around. It's safe and commonly used for counting down, or hashing/mod functions.

evandrix
  • 6,041
  • 4
  • 27
  • 38
  • 2
    I meant that as a comparison to try explain it by relating to something similar. I did qualify my statement later with the wrap around bit. Ah technicalities. – evandrix Feb 08 '12 at 13:21
-3

It probably depends a bit on your compiler. I had errors like this years ago, and sometimes you would get runtime error, other times it would basically "wrap" back to a really small number that would result from chopping off the highest level bits and leaving the remainder, i.e if it's a 32 bit unsigned int, and the result of your multiplication would be a 34 bit number, it would chop off the high order 2 bits and give you the remainder. You would probably have to try it on your compiler to see exactly what you get, which may not be the same thing you would get with a different compiler, especially if the overflow happens in the middle of an expression where the end result is within the range of an unsigned int.

  • **Unsigned** overflow does not depend on the compiler, it is standardized to have wrap-around semantics. It is only **signed** overflow that leads to undefined values, and may thus depend on the compiler. – cmaster - reinstate monica Apr 11 '17 at 13:29