TL; DR: To get a random integer over the entire range of possible integers, use:
function random_integer() { $min = defined('PHP_INT_MIN') ? PHP_INT_MIN : (-PHP_INT_MAX-1); return mt_rand($min, -1) + mt_rand(0, PHP_INT_MAX); }
For PHP 7 you can use random_int() .
Under the hood ( 1 , 2 ), PHP does this:
$number = random_number_between_0_and_0x7FFFFFFF_using_Mersenne_Twister; $number = $min + (($max - $min + 1.0) * ($number / (0x7FFFFFFF + 1.0)));
Pay attention to $max - $min . When max is set to the upper end and min is something negative, an overflow occurs. Therefore, the maximum range is PHP_INT_MAX . If your maximum value is PHP_INT_MAX , then your minimum is necessarily 0 .
Now for the background. PHP implements the 32-bit Mersenne Twister algorithm. This gives random integers between [0 and 2 ^ 31-1). If you request any other range, PHP scales this number using the simple binning function. This binning function includes subtraction, which can lead to overflow, and this problem.
Thus, if you want to get a range larger than can be represented as an integer in PHP, you need to add the intervals together, for example:
mt_rand(PHP_INT_MIN, -1) + mt_rand(0, PHP_INT_MAX);
Please note that PHP_INT_MIN available since PHP 7, so you will need to calculate the appropriate minimum for your environment before that.
Note that 2 ^ 31-1 is what getrandmax() returns. People mistakenly believe that getrandmax() will return 2 ^ 63-1 on a 64-bit machine. It is not true. getrandmax() returns the maximum integer returned by the algorithm, which is always 2 ^ 31-1.