'Discrepancy in Squaring a number stored in double format

I am trying to square a number x but there seems to be some discrepancy in precision while squaring it using Math.pow() and squaring it using multiplication.

public class MyClass {
    public static void main(String args[]) {
        long x = 1250075001;
        System.out.println(x*x);
        System.out.println(Math.pow((double)x,2.0));
    }
}

OUTPUT:

1562687508125150001
1.56268750812514995E18

The deviation is both the results in shown in bold

1562687508125150001
1.56268750812514995E18

I am not an expert in double arithmetic and how Math.pow() function works.
I tried reading some online articles on IEEE double standard and Math.pow() but it didn't help and that's why I came to the Stack Overflow community.



Solution 1:[1]

The number 1250075001, as a double, is stored as (sign ignored)

Exponent   Mantissa (52 bits)
  +30      (1.)0010101000001010100001011110010000000000000000000000

Note that this exactly represents 1250075001 since this integer still fits within 53 bits in binary form.

When you square this number, the exponent doubles to 60, and the mantissa is squared to become (1.)010110101111110010000000001001011000101111010110101100110001 (60 bits). As the mantissa must fit within 52 bits, the last 8 bits are truncated. Thus, you lose 001100012 = 49 from the true result i.e., instead of 1562687508125150001, you'll get 1562687508125149952 which is stored as

Exponent   Mantissa (52 bits)
  +60      (1.)0101101011111100100000000010010110001011110101101011

You can play with binary converter/calculator here, or with demonstration of IEEE 754 standard here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1