Hey internals,

As we’re moving to clean some things up in PHP 7, I think it might be worth 
looking at the rand()/mt_rand() situation.

Currently, we have two standard-library functions to obtain a random number: 
rand() and mt_rand(). rand() uses the C standard library function, which on 
many stdlibs is slow or has a limited range (e.g. Win32 rand()’s maximum return 
value is SHORT_MAX). As a result, a drop-in replacement was added, mt_rand(), 
which uses Mersenne Twister-based random number generator that’s probably 
better than what the C standard library provides.

Having two different random number functions is confusing to new users, and an 
oft-cited issue with PHP’s standard library. Intuitively, a user would expect 
rand() to be the function to get a random number, but actually they should be 
using mt_rand(), which is usually better. 

Another issue is the fact we allow random numbers to be seeded with srand() and 
mt_srand(). We have automatically seeded the random number generator for a 
while now, so there is no need to do it manually. We also explicitly do not 
guarantee that the random number generator will always produce the same output 
given the same seed, and in fact we’ve changed mt_rand()'s behaviour in the 
past. This eliminates the primary use-case for manual seeding when there is 
automatic seeding: predictable output for procedural generation.

Finally, a third issue is that mt_rand() does not produce good quality numbers 
on 64-bit platforms. mt_rand() will always produce a 32-bit value internally, 
and scale it up or down to fit the user-specified range. Unfortunately, this 
means that values for the $max parameter beyond 2^31 - 1 produce numbers with 
poor granularity.

Given all these, I would suggest that for PHP 7, we:

  * Get rid of rand(), srand() and getrandmax()
  * Rename mt_rand(), mt_srand() and mt_getrandmax() to rand(), srand(), and 
getrandmax() but add mt_* aliases for backwards-compatibility
  * Make mt_srand() and srand() do nothing and produce a deprecation notice
  * Use a 64-bit random number generation algorithm on 64-bit platforms (or 
invoke the 32-bit generator twice)

The end result should be that PHP has just one random number generation 
function, rand(), which can produce the full range from PHP_INT_MIN to 
PHP_INT_MAX with no scaling. This would be far more intuitive, I think.

Would that sound good?

Thanks!
--
Andrea Faulds
http://ajf.me/





--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to