Случайное плавание между 0 и 1 в PHP

Как генерировать случайное значение float между 0 и 1 в PHP?

Я ищу эквивалент PHP для Math.random() Java.

Вы можете использовать стандартную функцию: lcg-value

Вот еще одна функция, заданная в rand docs:

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

Пример из документации:

 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())); } } 

обновление: забудьте этот ответ, он не работает wit php -v> 5.3

Как насчет

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

?

это работает идеально для меня, и это не только для 0 – 1, например, между 1.0 – 15.0

  floatVal(rand(1, 15).'.'.rand(1, 9)); 
 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 

или используйте большее число, если вы хотите больше цифр после десятичной точки

 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; } 

пример:

 echo mt_rand_float(0, 1); 

результата: 0.2

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

результата: 3.219

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

результата: 4.52

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

результата: 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"; 

Решение для PHP 7. Производит случайное число в [0,1) . т.е. включает 0 и исключает 1.

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

Большинство ответов использует mt_rand . Однако mt_getrandmax() обычно возвращает только 2147483647 . Это означает, что у вас есть только 31 бит информации, в то время как у double есть мантисса с 52 битами, что означает, что существует плотность не менее 2^53 для чисел от 0 до 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]; } 

Обратите внимание, что приведенный выше код работает только на 64-битных машинах с порядком байтов Litte-Endian и представлением IEEE754 в стиле Intel. (совместимы с x64 разрядными компьютерами). К сожалению, PHP не позволяет битовую перестановку прошлых границ, int32 int32, поэтому вам нужно написать отдельную функцию для Big-Endian.

Вы должны заменить эту строку:

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

с его сторонником:

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

Разница заметна только тогда, когда функция называется большим количеством раз: 10^9 или более.

Тестирование, если это работает

Должно быть очевидно, что мантисса следует хорошему равномерному приближению распределения, но менее очевидно, что сумма большого количества таких распределений (каждая с кумулятивно уменьшенной пополам случайностью и амплитудой) является однородной.

Бег:

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

Производит выход 0.49999928273099 (или аналогичное число, близкое к 0,5).

Я нашел ответ на 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) 

Таким образом, вы могли бы сделать

 randomFloat(0,1); 

или просто

 mt_rand() / mt_getrandmax() * 1; 

как насчет:

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

вероятно, будет работать нормально … надеюсь, это поможет вам.