web-dev-qa-db-fra.com

Flotteur aléatoire entre et 1 po PHP

Comment générer un float aléatoire compris entre 0 et 1 en PHP?

Je recherche l'équivalent PHP de Math.random() de Java.

32
Goaler444

Vous pouvez utiliser la fonction standard: lcg_value () .

Voici une autre fonction donnée sur le Rand () docs:

// auxiliary function
// returns random number with flat distribution from 0 to 1
function random_0_1() 
{
    return (float)Rand() / (float)getrandmax();
}
33
Denys Séguret

Exemple de documentation: 

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

update: oubliez cette réponse ça ne marche pas avec php -v> 5.3

Qu'en est-il de

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

cela fonctionne parfaitement pour moi, et ce n'est pas seulement pour 0 - 1 par exemple entre 1.0 - 15.0

 floatVal(Rand(1, 15).'.'.Rand(1, 9)); 
5
john Smith
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
YarikKotsur
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;
}

Exemple:

echo mt_Rand_float(0, 1);

résultat: 0.2

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

résultat: 3.219

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

résultat: 4.52

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

résultat: 0.69

4
viruseg
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

ou utilisez un plus grand nombre si vous voulez plus de chiffres après la virgule décimale

4
Paul D Martini
$random_number = Rand(1,10).".".Rand(1,9);
2
Mohit Varshney
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";
1
Tahir Yasin

La plupart des réponses utilisent mt_Rand. Cependant, mt_getrandmax() ne renvoie généralement que 2147483647. Cela signifie que vous ne disposez que de 31 bits d'information, tandis qu'un double a une mantisse de 52 bits, ce qui signifie qu'il existe une densité d'au moins 2^53 pour les nombres compris entre 0 et 1. 

Cette approche plus compliquée vous donnera une distribution plus fine: 

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

Veuillez noter que le code ci-dessus ne fonctionne que sur les ordinateurs 64 bits avec un ordre d'octets Litte-Endian et une représentation IEEE754 de type Intel. (x64- les ordinateurs compatibles auront ceci). Malheureusement, PHP n'autorise pas le décalage de bits après les limites de taille int32, vous devez donc écrire une fonction distincte pour Big-Endian. 

Vous devriez remplacer cette ligne: 

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

avec son homologue big-endian:

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

La différence n’est notable que lorsque la fonction est appelée un grand nombre de fois: 10^9 ou plus. 

Vérifier si cela fonctionne

Il devrait être évident que la mantisse suit une approximation de distribution uniforme de Nice, mais il est moins évident que la somme d'une grande quantité de telles distributions (chacune avec une chance et une amplitude cumulées de moitié) est uniforme. 

Fonctionnement: 

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

Produit une sortie de 0.49999928273099 (ou un nombre similaire proche de 0.5). 

0
aphid

Solution for PHP 7. Génère un nombre aléatoire dans [0,1). c'est-à-dire comprend 0 et exclut 1.

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

J'ai trouvé la réponse sur 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)

Alors tu pourrais faire 

randomFloat(0,1);

ou simple 

mt_Rand() / mt_getrandmax() * 1;
0
pwqwerty123