如何在PHP中生成0到1之间的随机浮点数?
我正在寻找PHP中等同于Java的Math.random()
的函数。
// auxiliary function
// returns random number with flat distribution from 0 to 1
function random_0_1()
{
return (float)rand() / (float)getrandmax();
}
mt_rand()
被认为比 rand()
生成的随机数更加随机。翻译后的代码为:return (float) mt_rand() / (float) mt_getrandmax();
。 - Tim S.rand
现在是 mt_rand
的别名。 - apokryfos文档示例:
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()));
}
}
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);
result: 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');
result: 0.69
更新:忘记这个答案,它不适用于 PHP -v > 5.3。
那么呢?
floatVal('0.'.rand(1, 9));
对我来说,这很完美,不仅适用于0-1的范围,例如在1.0-15.0之间也可以使用。
floatVal(rand(1, 15).'.'.rand(1, 9));
$random_number = rand(1,10).".".rand(1,9);
PHP 7的解决方案。生成[0,1)
范围内的随机数,即包括0但不包括1。
function random_float() {
return random_int(0, 2**53-1) / (2**53);
}
感谢评论区的Nommyde
指出我的错误。
>>> number_format((2**53-1)/2**53,100)
=> "0.9999999999999998889776975374843459576368331909179687500000000000000000000000000000000000000000000000"
>>> number_format((2**53)/(2**53+1),100)
=> "1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
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";
(int)(random_float() * 10)
将返回0到9之间的一个值,每个值的机会相等。如果在十亿次中有一次返回1,那么很少会返回10。mt_rand() / (getrandmax() + 1)
有时候分布会有微小的差异,通常是在0到9之间,由于精度问题,0可能比9稍微更容易出现。但这通常只存在于十亿分之一左右,不像上述问题那么严重,因为上述问题可能会导致计算结果超出范围从而无效。
Java的Math.random也永远不会产生值为1的情况。这部分原因在于解释它具体做什么很麻烦。它返回0到小于1的值。这就像是Zeno的箭,它永远不会到达1。这不是人们通常会说的东西。相反,人们倾向于说从0到1之间或者0到1之间,但这些都是错误的。
这在错误报告中有点好笑。例如,使用lcg_value的任何PHP代码如果没有考虑到这一点,可能会在大约20亿次中出现一次故障,如果它符合其文档说明,但这使得忠实地重现变得异常困难。
这种偏移一个错误是嵌入式设备中通常遇到的“只需关闭并重新打开”问题的常见来源之一。
rand()
文档中有一些示例。 - Michael Berkowski