Sorry for the bad title, but I dunno how to call this.
echo rand(0,10e20) . "\n"; // bad
echo rand(0,10e19) . "\n"; // bad
echo rand(0,10e18) . "\n"; // bad
echo rand(0,10e17) . "\n"; // OK
echo rand(0,10e16) . "\n";
echo rand(0,10e15) . "\n\n";
var_dump(10e20); // float
var_dump(10e15); // float
Output:
Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 1
Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 2
Warning: rand() expects parameter 2 to be integer, float given in /srv/webroot-sandbox/index.php(73) : eval()'d code on line 3
578009006101638016
69608699344098568
7596902768127620
float(1.0E+21)
float(1.0E+16)
Can someone explain what's going on? This is PHP 7, it worked fine in PHP 5 (well, at least I didn't get any warnings).
The precision of the float for large numbers is much lower than an int.
6 Answers. Show activity on this post. They are totally different - typically int is just a straightforward 2's complement signed integer, while float is a single precision floating point representation with 23 bits of mantissa, 8 bits exponent and 1 bit sign (see http://en.wikipedia.org/wiki/IEEE_754-2008).
PHP ints are signed 64bit values (unless you're on a 32bit install), so they go (roughly)
-9,223,372,036,854,775,808 -> +9,223,372,036,854,775,808
In scientific notation, -9.2e18 -> +9.2e18
So your "bad" values are simply integers that are too large to store as integers, and PHP is converting to float to try and preserve as much of the value as is possible.
And since you have 10e18
, that's actually 1e19
, and outside the max_int range.
Your question can be platform dependent as the integer range of a:
-2,147,483,648
to 2,147,483,647
-9,223,372,036,854,775,808
to 9,223,372,036,854,775,808
For me, running a 64 bit system it gives the following result.
var_dump(10e20 > PHP_INT_MAX); // true
var_dump(10e19 > PHP_INT_MAX); // true
var_dump(10e18 > PHP_INT_MAX); // true
var_dump(10e17 > PHP_INT_MAX); // false
var_dump(10e16 > PHP_INT_MAX); // false
var_dump(10e15 > PHP_INT_MAX); // false
This output directly correlates with your results and might explain a fiddle or your webhost to show different results.
The reason it behave differently on PHP 7 is explained here:
Previously, internal functions would silently truncate numbers produced from float-to-integer coercions when the float was too large to represent as an integer. Now, an E_WARNING will be emitted and NULL will be returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With