Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Вы можете использовать стандартную функцию: 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();
}

Ответ 2

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

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

Ответ 3

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

Что насчет

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

?

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

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

В большинстве ответов используется 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 -разграниченных границ, поэтому вам нужно написать отдельную функцию для 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).

Ответ 11

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

Ответ 12

как насчет:

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

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