I know about weird stuff with precision errors, but I can't fathom,
Why is (long)9223372036854665200d
giving me 9223372036854665216
?
I know about weird stuff with precision errors, but I can't fathom,
Why is (long)9223372036854665200d
giving me 9223372036854665216
?
Because doubles don't have that much precision. Why are you doing such a strange thing? Change the d to l.
Doubles
have 52-53 bit precision, whereas along
has 64 bit precision (for integers only). The loss of precision in a double is used to represent the exponent, which allows adouble
to represent larger/smaller numbers than along
can.Your number is 19 digits long, whereas a double can only store roughly 16 digits of (decimal) integer data. Thus the final number ends up being rounded.
Reference: Double - Wikipedia
You are assuming that limited precision means that it is represented in decimal so is limited to 15 or 16 digits. Actually it is represented in binary and limited to 53 bits of precision.
double
takes the closest representable value.prints
9223372036854665200d
is a constant of typedouble
. However,9223372036854665200
does not fit in adouble
without loss of precision. Adouble
only has 52 bits of mantissa, whereas the number in question requires 63 bits to be represented exactly.The nearest
double
to9223372036854665200d
is the number whose mantissa equals1.1111111111111111111111111111111111111111111110010100
in binary and whose exponent is 63 (decimal). This number is none other than9223372036854665216
(call itU
).If we decrease the mantissa one notch to
1.1...0011
, we get9223372036854664192
(call itL
).The original number is between
L
andU
and is much closer toU
than it is toL
Finally, if you think that this truncation of the mantissa ought to result in a number that ends in a bunch of zeros, you're right. Only it happens in binary, not in decimal:
U
in base-16 is0x7ffffffffffe5000
andL
is0x7ffffffffffe4c00
.Because doubles have limited precision. Your constant has more significant digits than a double can keep track of, so it loses them.