If you evaluate
(Math.PI).ToString("G51")
the result is
"3,141592653589793115997963468544185161590576171875"
Math.Pi
is correct up to the 15th decimal which is in accordance with the precision of a double
. "G17" is used for round tripping, so I expected the ToString
to stop after "G17", but instead it continued to produce numbers up to "G51".
Q Since the digits after 15th decimal are beyond the precision afforded by the 53 bits of mantissa, how are the remaining digits calculated?
CodePudding user response:
The .ToString("G51")
method uses 'school math'. First it takes the integer part, then it multiplies the Remainder
by 10, use the integer part of that calculation and multiplies the Remainder
part by 10.
It will keep doing that as long as there is a remainder and up to 51
decimal digits.
Since double
has an exponent, it will keep having a remainder with about 18 decimal digits, which produces the next digit in ToString
method.
However, as you have seen, the Remainder
part is not accurate but simply a result of a math function.
CodePudding user response:
A double has a 53 bit mantissa which corresponds to 15 decimals
A double has a 53 bit mantissa which corresponds to roughly 15 decimals.
Math.Pi is truncated at 53 bits in binary, which is not precisely equal to
3.1415926535897
but it's also not quite equal to
3.14159265358979
, etc.
Just like 1/3 is not quite 0.3, or 0.33, etc.
If you continue the decimal expansion long enough it will eventually start repeating, since Math.PI, unlike π is a rational number.