If I have two unsigned long long values say pow(10,18) and pow (10,19) and I multiply them and store the output in another variable of type unsigned long long...the value which we get is obviously not the answer but does it have any logic? We get a junk type of value each time we try to this with arbitrarily large numbers, but do the outputs have any logic with the input values?
-
related: http://stackoverflow.com/questions/9193880/overflowing-of-unsigned-int – Nate Kohl Jan 07 '14 at 19:02
-
If they are constants then just type them in stead of computing them each time the program is executed – Ed Heal Jan 07 '14 at 19:04
2 Answers
Unsigned integral types in C++ obey the rules of modular arithmetic, i.e. they represent the integers modulo 2N, where N is the number of value bits of the integral type (possibly less than its sizeof
times CHAR_BIT
); specifically, the type holds the values [0, 2N).
So when you multiply two numbers, the result is the remainder of the mathematical result divided by 2N.
The number N is obtainable programmatically via std::numeric_limits<T>::digits
.

- 464,522
- 92
- 875
- 1,084
Yes, there's a logic.
As KerreK wrote, integers are "wrapped around" the 2N bits that constitute the width of their datatype.
To make it easy, let's consider the following:
#include <iostream>
#include <cmath>
using namespace std;
int main() {
unsigned char tot;
unsigned char ca = 200;
unsigned char ca2 = 200;
tot = ca * ca2;
cout << (int)tot;
return 0;
}
(try it: http://ideone.com/nWDYjO)
In the above example an unsigned char is 1 byte wide (max 255 decimal value), when multiplying 200 * 200 we get 40000. If we try to store it into the unsigned char it won't obviously fit.
The value is then "wrapped around", that is, tot gets the result of the following
(ca*ca2) % 256
where 256 are the bit of the unsigned char (1 byte), 28 bits
In your case you would get
(pow(10,18) * pow (10,19)) % 2number_of_bits_of_unsigned_long_long(architecture_dependent)

- 43,032
- 26
- 132
- 246
-
1
-
-
1To be pedantic, the *N* is not necessarily the width of the type. In general there may be padding. Only the `char` types and the `intNN_t`/`uintNN_t` types are guaranteed not to have padding. – Kerrek SB Jan 07 '14 at 21:46