php PHP中0到1之间的随机浮点数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14141212/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Random Float between 0 and 1 in PHP
提问by Goaler444
How does one generate a random float between 0 and 1 in PHP?
如何在 PHP 中生成 0 和 1 之间的随机浮点数?
I'm looking for the PHP's equivalent to Java's Math.random().
我正在寻找相当于 Java 的 PHP 的Math.random().
回答by Denys Séguret
You may use the standard function: lcg_value().
您可以使用标准函数:lcg_value()。
Here's another function given on the rand()docs:
这是rand()文档中给出的另一个函数:
// auxiliary function
// returns random number with flat distribution from 0 to 1
function random_0_1()
{
return (float)rand() / (float)getrandmax();
}
回答by Pierrickouw
Example from documentation :
文档中的示例:
function random_float ($min,$max) {
return ($min+lcg_value()*(abs($max-$min)));
}
回答by YarikKotsur
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()));
}
}
回答by Paul D Martini
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
或者如果您想要小数点后更多位数,请使用更大的数字
回答by john Smith
update: forget this answer it doesnt work wit php -v > 5.3
更新:忘记这个答案它在 php -v > 5.3 中不起作用
What about
关于什么
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
这对我来说是完美的,它不仅适用于 0 - 1,例如 1.0 - 15.0
floatVal(rand(1, 15).'.'.rand(1, 9));
回答by viruseg
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
结果:0.2
echo mt_rand_float(3.2, 3.23, '000');
result: 3.219
结果:3.219
echo mt_rand_float(1, 5, '00');
result: 4.52
结果:4.52
echo mt_rand_float(0.56789, 1, '00');
result: 0.69
结果:0.69
回答by Mohit Varshney
$random_number = rand(1,10).".".rand(1,9);
回答by Tahir Yasin
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";
回答by mpen
Solution for PHP 7. Generates random number in [0,1). i.e. includes 0 and excludes 1.
PHP 7 的解决方案。在[0,1). 即包括 0 不包括 1。
function random_float() {
return random_int(0, PHP_INT_MAX-1)/PHP_INT_MAX;
}
回答by aphid
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^53for the numbers between 0 and 1.
大多数答案都在使用mt_rand. 但是,mt_getrandmax()通常只返回2147483647. 这意味着您只有 31 位信息,而双精度数具有 52 位的尾数,这意味着2^530 和 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 = " $z = " $z = pack("S", $e << 4) . "function randomNumbers() {
$f = 0.0;
for($i = 0; $i < 1000000; ++$i) {
$f += \math::rand_754_01();
}
echo $f / 1000000;
}
##代码####代码####代码####代码####代码##";
##代码####代码####代码####代码####代码##" . pack("S", $e << 4);
##代码####代码####代码####代码####代码##" . 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.
请注意,上述代码仅适用于具有 Litte-Endian 字节顺序和 Intel 风格 IEEE754 表示的 64 位机器。( -x64兼容的计算机将具有此功能)。不幸的是,PHP 不允许位移超过int32大小的边界,因此您必须为 Big-Endian 编写一个单独的函数。
You should replace this line:
您应该替换此行:
##代码##with its big-endian counterpart:
与其 big-endian 对应物:
##代码##The difference is only notable when the function is called a large amount of times: 10^9or more.
只有在函数被大量调用时,差异才会显着:10^9或更多。
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:
跑步:
##代码##Produces an output of 0.49999928273099(or a similar number close to 0.5).
产生0.49999928273099(或接近 0.5 的类似数字)的输出。

