Search code examples
c++integerprecisionmultiplication

A C++ large integer precision question during multiplication


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)?


Solution

  • 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).