9

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).

6
  • 2
    Still searching but MIGHT be that it exceeds the size of the int... Commented Mar 2, 2016 at 19:12
  • hmm maybe it tries to cast and fails at certain magnitude? But funny that it worked OK in PHP 5 Commented Mar 2, 2016 at 19:12
  • according to the manual: php.net/manual/en/language.types.integer.php Once you go outside the limit, you get in error. And this is specific to php7. Commented Mar 2, 2016 at 19:16
  • hm yea just found it myself on google. Still worth an answer, I won't be the only one to stumble upon this. Commented Mar 2, 2016 at 19:17
  • var_dump doesn't care if you provide float or int, but rand does. Did you try to set the precision in php7? Commented Mar 2, 2016 at 19:27

2 Answers 2

11

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Would be interesting to also compare this to PHP 5's behaviour, regrettably I have upgraded already...
@MightyPork, the behavior is the same with any system, 32-bit integers max is 2^32/2-1 and 64-bit integer max is 2^64/2-1. (Unsigned would be 2^32-1, 2^64-1 but PHP doesn't allow unsigned integers if IIRC)
my 5.5.9 matches above. But note that in Windows, php5 treated all ints as 32bit, regardless of what the underlying platform is. e.g. phpwin 64bit was still using 32bit ints.
why I wanted to try php5 is the rand() warning didn't occur before. Kinda curious how it managed to fit the large number to int back then.
it would've done the same thing, since rand() expects ints. it may just have been a silent error before, and PHP7 upgraded it to a fullblown warning. I don't get any warnings at all on 5.5.9 with an over-sized int.
9

Your question can be platform dependent as the integer range of a:

  • 32 bit platform is -2,147,483,648 to 2,147,483,647
  • 64 bit platform is -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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.