>
I just find it weird that, on a platform where 64-bit positive integer values can be stored exactly, it is considered acceptable that all other integer values be rounded to 53 bits of precision.
I need to test again, but IMHO this depends on the number before the operation being a float or not.
AFAIK is exponentiation ** using an approximation algorithm and hence always producing a float.
So even if 2**53 (-1) should be a perfectly "whole number" it's stored as a float.
But that's speculation, I'm thinking of writing simple test code using only basic operations.
This could be translated to different dynamically typed languages to test their behavior.
update
I can't see how your wtf-example shows any rounding to 2**53.
Your floats have 64 bits leaving 53 for the mantissa and ~0 == 2^64-1 , hence there is no way to represent a whole number ~0+1 loss free.
Going up to 128bit floats will just replicate the situation on 32bit systems with 64bit floats.
update
OK I tried to nail down the weirdness, please note in the first example I'm constructing 2^53-1 and everything goes fine, even since ** will always produce a NV, summing them up will convert back to IV.
lanx:$ perl -MDevel::Peek -E'$x+=2**$_ for 0..52;Dump ($x);Dump($x+1)'
SV = IV(0x64c9edf22bb0) at 0x64c9edf22bc0
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 9007199254740991
SV = IV(0x64c9edf838d0) at 0x64c9edf838e0
REFCNT = 1
FLAGS = (PADTMP,IOK,pIOK)
IV = 9007199254740992
Now the same with 2^54-1, because the last element of the sum is the NV 2**53 which doesn't fit into the mantissa, we are stuck in NV even after adding an IV.
lanx:$ perl -MDevel::Peek -E'$x+=2**$_ for 0..53;Dump ($x);Dump($x+1);
+say "*** WTF *** " if $x == $x+1'
SV = PVNV(0x5ea09827d340) at 0x5ea0982abd00
REFCNT = 1
FLAGS = (NOK,pNOK)
IV = 9007199254740991
NV = 18014398509481984
PV = 0
SV = NV(0x5ea09830cb18) at 0x5ea09830cb30
REFCNT = 1
FLAGS = (PADTMP,NOK,pNOK)
NV = 18014398509481984
*** WTF ***
The real issue here is the ** operand, it should ideally produce an integer since 2 and 53 are integers and they fit into IV.
But even special casing the X**Y algorithm for integer results isn't trivial.
- 2**65 would still need to produce an NV
- 4**0.5 would need to be IV 2
|