If I run the following program:
#include <iostream>
int main()
{
using namespace std;
uint64_t f12 = 18446744073709551568;
uint64_t f3 = 2;
uint64_t f123 = f12 * f3;
cout << f12 << endl;
cout << f3 << endl;
cout << f123 << endl;
return 0;
}
I get as output:
18446744073709551568
2
18446744073709551520
I don't understand why 2 times f12 results in a value that is less (by exactly 48). If the value rolled over due to reaching the size of the uint64 value, wouldn't it be quite different (unless this is an extreme coincidence)?
You can chalk it up to "extreme coincidence". 18446744073709551568 in binary is
FFFFFFFFFFFFFFD0
We all discovered when we learned binary math that multiplication by two is equivalent to a left shift, which becomes:
FFFFFFFFFFFFFFA0
Note that D0
is
11010000
in binary, with the high bit set, so shifting left the lower 8 bits becomes
10100000
or A0
(with the high bit getting carried left).
And now, by computing what's FFFFFFFFFFFFFFA0
in decimal you'll get the answer to your question (you are kind of getting a clue already, since A0
is less than D0
by 30
hexadecimal, which happens to be, purely by accident, 48).