'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 |