Home » Php » Random Float between 0 and 1 in PHP

# Random Float between 0 and 1 in PHP

Questions:

How does one generate a random float between 0 and 1 in PHP?

I’m looking for the PHP’s equivalent to Java’s `Math.random()`.

You may use the standard function: lcg_value().

Here’s another function given on the rand() docs:

``````// auxiliary function
// returns random number with flat distribution from 0 to 1
function random_0_1()
{
return (float)rand() / (float)getrandmax();
}
``````

Example from documentation :

``````function random_float (\$min,\$max) {
return (\$min+lcg_value()*(abs(\$max-\$min)));
}
``````

``````class SomeHelper
{
/**
* Generate random float number.
*
* @param float|int \$min
* @param float|int \$max
* @return float
*/
public static function rand(\$min = 0, \$max = 1)
{
return (\$min + (\$max - \$min) * (mt_rand() / mt_getrandmax()));
}
}
``````

``````rand(0,1000)/1000 returns:
0.348 0.716 0.251 0.459 0.893 0.867 0.058 0.955 0.644 0.246 0.292
``````

or use a bigger number if you want more digits after decimal point

update:
forget this answer it doesnt work wit php -v > 5.3

``````floatVal('0.'.rand(1, 9));
``````

?

this works perfect for me, and it´s not only for 0 – 1 for example between 1.0 – 15.0

`````` floatVal(rand(1, 15).'.'.rand(1, 9));
``````

``````function mt_rand_float(\$min, \$max, \$countZero = '0') {
\$countZero = +('1'.\$countZero);
\$min = floor(\$min*\$countZero);
\$max = floor(\$max*\$countZero);
\$rand = mt_rand(\$min, \$max) / \$countZero;
return \$rand;
}
``````

example:

``````echo mt_rand_float(0, 1);
``````

result: 0.2

``````echo mt_rand_float(3.2, 3.23, '000');
``````

result: 3.219

``````echo mt_rand_float(1, 5, '00');
``````

result: 4.52

``````echo mt_rand_float(0.56789, 1, '00');
``````

result: 0.69

``````\$random_number = rand(1,10).".".rand(1,9);
``````

``````function frand(\$min, \$max, \$decimals = 0) {
\$scale = pow(10, \$decimals);
return mt_rand(\$min * \$scale, \$max * \$scale) / \$scale;
}

echo "frand(0, 10, 2) = " . frand(0, 10, 2) . "\n";
``````

Solution for PHP 7. Generates random number in `[0,1)`. i.e. includes 0 and excludes 1.

``````function random_float() {
return random_int(0, PHP_INT_MAX-1)/PHP_INT_MAX;
}
``````

Most answers are using `mt_rand`. However, `mt_getrandmax()` usually returns only `2147483647`. That means you only have 31 bits of information, while a double has a mantissa with 52 bits, which means there is a density of at least `2^53` for the numbers between 0 and 1.

This more complicated approach will get you a finer distribution:

``````function rand_754_01() {
// Generate 64 random bits (8 bytes)
\$entropy = openssl_random_pseudo_bytes(8);
// Create a string of 12 '0' bits and 52 '1' bits.
\$x = 0x000FFFFFFFFFFFFF;
\$first12 = pack("Q", \$x);
// Set the first 12 bits to 0 in the random string.
\$y = \$entropy & \$first12;
// Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022.
// Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc.
\$e = 1022;
while(\$e > 1) {
if(mt_rand(0,1) == 0) {
break;
} else {
--\$e;
}
}
// Pack the exponent properly (add four '0' bits behind it and 49 more in front)
\$z = "function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } function rand_754_01() { // Generate 64 random bits (8 bytes) \$entropy = openssl_random_pseudo_bytes(8); // Create a string of 12 '0' bits and 52 '1' bits. \$x = 0x000FFFFFFFFFFFFF; \$first12 = pack("Q", \$x); // Set the first 12 bits to 0 in the random string. \$y = \$entropy & \$first12; // Now set the first 12 bits to be 0[exponent], where exponent is randomly chosen between 1 and 1022. // Here \$e has a probability of 0.5 to be 1022, 0.25 to be 1021, etc. \$e = 1022; while(\$e > 1) { if(mt_rand(0,1) == 0) { break; } else { --\$e; } } // Pack the exponent properly (add four '0' bits behind it and 49 more in front) \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); // Now convert to a double. return unpack("d", \$y | \$z)[1]; } " . pack("S", \$e << 4);
// Now convert to a double.
return unpack("d", \$y | \$z)[1];
}
``````

Please note that the above code only works on 64-bit machines with a Litte-Endian byte order and Intel-style IEEE754 representation. (`x64`-compatible computers will have this). Unfortunately PHP does not allow bit-shifting past `int32`-sized boundaries, so you have to write a separate function for Big-Endian.

You should replace this line:

``````    \$z = " \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4);  \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4);  \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4);  \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4);  \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4);  \$z = "\0\0\0\0\0\0" . pack("S", \$e << 4); " . pack("S", \$e << 4);
``````

with its big-endian counterpart:

``````    \$z = pack("S", \$e << 4) .  " \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0";  \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0";  \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0";  \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0";  \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0";  \$z = pack("S", \$e << 4) . "\0\0\0\0\0\0"; ";
``````

The difference is only notable when the function is called a large amount of times: `10^9` or more.

Testing if this works

It should be obvious that the mantissa follows a nice uniform distribution approximation, but it’s less obvious that a sum of a large amount of such distributions (each with cumulatively halved chance and amplitude) is uniform.

Running:

``````function randomNumbers() {
\$f = 0.0;
for(\$i = 0; \$i < 1000000; ++\$i) {
\$f += \math::rand_754_01();
}
echo \$f / 1000000;
}
``````

Produces an output of `0.49999928273099` (or a similar number close to 0.5).

I found the answer on PHP.net

``````<?php
function randomFloat(\$min = 0, \$max = 1) {
return \$min + mt_rand() / mt_getrandmax() * (\$max - \$min);
}

var_dump(randomFloat());
var_dump(randomFloat(2, 20));
?>

float(0.91601131712832)
float(16.511210331931)
``````

So you could do

``````randomFloat(0,1);
``````

or simple

``````mt_rand() / mt_getrandmax() * 1;
``````

``````echo (float)('0.' . rand(0,199999));