Question

I'm experimenting with PHP representation of BIGINT values (which are keys in tables), and to test how PHP handles large numbers as strings/float values i wrote a tiny test:

<?php
 echo "PHP_INT_MAX=".PHP_INT_MAX."\n"; 
 $x = "9223372036854775107";
 echo "Defining x as : 9223372036854775107\n";
 $y = floatval($x);
 echo "float of x: ".$y."\n";
 echo "float to string using strval: ".strval($y)."\n";
 echo "float to string using sprintf: ".sprintf( "%.0f", $y)."\n";
?>

So I'm curious about the output:

PHP_INT_MAX=9223372036854775807
Defining x as : 9223372036854775107
float of x: 9.2233720368548E+18
float to string using strval: 9.2233720368548E+18
float to string using sprintf: 9223372036854774784

So why am I getting values which don't match? (precision in php.ini file = 14)

Was it helpful?

Solution

It's all about float type. PHP uses common standart for it IEEE 754.

Float size is 64. On 64 system integer size is 64 too.

But max float number without fractional part without loss of precision is 9007199254740991. Numbers more than those lose their precision, because of format storing float numbers.

Between 2^52=4,503,599,627,370,496 and 2^53=9,007,199,254,740,992 the representable numbers are exactly the integers. For the next range, from 2^53 to 2^54, everything is multiplied by 2, so the representable numbers are the even ones, etc. Conversely, for the previous range from 2^51 to 2^52, the spacing is 0.5, etc.

The spacing as a fraction of the numbers in the range from 2^n to 2^n+1 is 2^n−52. The maximum relative rounding error when rounding a number to the nearest representable one (the machine epsilon) is therefore 2^−53.

Double-precision floating-point format

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top