That's not true. Floating points can represent a large range of integers exactly, and that range for a double is bigger than the range of an unsigned 32 bit int.
Type Min Max
-------------------------------- -------- -----------
signed n-bit int -2^(n-1) (2^(n-1))-1
unsigned n-bit int 0 (2^n)-1
IEEE float with n-bit mantissa -2^(n+1) 2^(n+1)
Double has n=52, so 4294967295 isn't the maximum that can be held without Math::BigInt.
Type Min Max
-------------------------------- ----------------- ----------------
signed 32-bit integer -2147483648 2147483647
unsigned 32-bit integer 0 4294967295
IEEE float with 52-bit mantissa -9007199254740992 9007199254740992
Demo:
$x = 2**(52+1);
# For doubles, format "%.17e" will tell you if
# the number is stored with no loss of precision
# because log10(2**(n+1)) < 17.
printf("%.17e\n\n", $x);
$x -= 5;
for (1..10) {
printf("%f\n", $x);
$x++;
}
9.00719925474099200e+015 <-- That's exact.
9007199254740987.000000
9007199254740988.000000
9007199254740989.000000
9007199254740990.000000
9007199254740991.000000
9007199254740992.000000
9007199254740992.000000 <-- Least significant
9007199254740992.000000 bit dropped.
9007199254740992.000000
9007199254740992.000000
|