randomize - random number php no repeat
FlotaciĆ³n aleatoria entre 0 y 1 en PHP (12)
$ random_number = rand (1,10). ".". rand (1,9);
¿Cómo se genera una flotación aleatoria entre 0 y 1 en PHP?
Estoy buscando el equivalente de PHP a Math.random()
Java.
Ejemplo de documentación:
function random_float ($min,$max) {
return ($min+lcg_value()*(abs($max-$min)));
}
Encontré la respuesta en 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)
Entonces podrías hacer
randomFloat(0,1);
o simple
mt_rand() / mt_getrandmax() * 1;
La mayoría de las respuestas están usando mt_rand
. Sin embargo, mt_getrandmax()
generalmente solo devuelve 2147483647
. Eso significa que solo tiene 31 bits de información, mientras que un doble tiene una mantisa con 52 bits, lo que significa que hay una densidad de al menos 2^53
para los números entre 0 y 1.
Este enfoque más complicado te dará una distribución más fina:
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];
}
Tenga en cuenta que el código anterior solo funciona en máquinas de 64 bits con un orden de bytes Litte-Endian y una representación IEEE754 al estilo Intel. (Las computadoras compatibles con x64
tendrán esto). Desafortunadamente, PHP no permite el cambio de bits pasado los límites de int32
int32, por lo que debe escribir una función separada para Big-Endian.
Debes reemplazar esta línea:
$z = "/0/0/0/0/0/0" . pack("S", $e << 4);
con su contraparte big-endian:
$z = pack("S", $e << 4) . "/0/0/0/0/0/0";
La diferencia solo es notable cuando la función se llama una gran cantidad de veces: 10^9
o más.
Probando si esto funciona
Debería ser obvio que la mantisa sigue una buena aproximación de distribución uniforme, pero es menos obvio que una suma de una gran cantidad de tales distribuciones (cada una con probabilidad y amplitud acumuladas a la mitad) es uniforme.
Corriendo:
function randomNumbers() {
$f = 0.0;
for($i = 0; $i < 1000000; ++$i) {
$f += /math::rand_754_01();
}
echo $f / 1000000;
}
Produce una salida de 0.49999928273099
(o un número similar cercano a 0.5).
Puede usar la función estándar: lcg_value() .
Aquí hay otra función dada en los documentos rand () :
// auxiliary function
// returns random number with flat distribution from 0 to 1
function random_0_1()
{
return (float)rand() / (float)getrandmax();
}
Solución para PHP 7. Genera un número aleatorio en [0,1)
. es decir, incluye 0 y excluye 1.
function random_float() {
return random_int(0, PHP_INT_MAX-1)/PHP_INT_MAX;
}
qué pasa:
echo (float)(''0.'' . rand(0,199999));
probablemente funcionaría bien ... espero que te ayude.
actualización: olvida esta respuesta, no funciona con php -v> 5.3
Qué pasa
floatVal(''0.''.rand(1, 9));
?
esto funciona perfecto para mí, y no es solo para 0 - 1, por ejemplo, entre 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;
}
ejemplo:
echo mt_rand_float(0, 1);
resultado: 0.2
echo mt_rand_float(3.2, 3.23, ''000'');
resultado: 3.219
echo mt_rand_float(1, 5, ''00'');
resultado: 4.52
echo mt_rand_float(0.56789, 1, ''00'');
resultado: 0.69
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()));
}
}
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";
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
o usa un número más grande si quieres más dígitos después del punto decimal