在PHP中生成0到1.0之间的随机浮点数。

70

可能是重复问题:
php中的随机浮点数

是否有可能创建一个在0和1.0之间的随机浮点数,例如0.4、0.8等。 我使用了rand函数,但它只接受整数。


4
PHP手册中关于mt_getrandmax有一个官方示例来完成这个操作。 - Gordon
我的错,我看了一下但没有找到那个问题。 - Matthew Underwood
参见:https://dev59.com/VXnZa4cB1Zd3GeqPvNiz#47190869 - caw
为什么不简单点呢?rand(0,1).".".rand(0,100) - spencerthayer
7个回答

127
mt_rand() / mt_getrandmax();

避免使用rand()函数,因为它通常依赖于平台的C rand()实现,生成的数字通常具有非常简单的模式。参见php.net上的这个评论更新:在php 7.1中,rand()已更改,现在只是mt_rand()的别名。因此,现在可以使用rand()

25
为了更恰当地模拟我认为标准随机化程序的0.0包含到1.0不包含的性质,可以使用mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax() - Erick Robertson
请参见 https://dev59.com/VXnZa4cB1Zd3GeqPvNiz#47190869,其中包含支持包括和排除两种变体的版本。 - caw
3
PHP 7.0中的rand函数和mt_rand使用相同的生成器。但是,当max小于min时,参数值的行为不同。 - Rolice
lcg_value()可以完成这个任务。要简单得多。不幸的是,这个问题已经被锁定,我无法用它来创建答案。(尽管这个问题比它的对应问题更受欢迎) - Lemmings19

37

那么仅仅将数字除以10呢?

$randomFloat = rand(0, 10) / 10;
var_dump($randomFloat);

//eg. float(0.7)

3
只有10种可能性之一,随机性的空间不大。 - Dracony
6
OP似乎只需要一位小数。当然,任何数字都可以被选中(rand(0, 10000) / 10000)以引起更多的小数和随机性。 - h2ooooooo
7
@Dracony,h2oooooo:严谨地说,随机性的数量并没有改变... - Oliver Charlesworth
@OliCharlesworth 当然,你是正确的 - 它同样随机,但有更多的小数位。 - h2ooooooo
@Dracony:...现在你有我的答案了 :-) https://dev59.com/pc8D0IgBFxS5KdRjkOQA#14155720 - Francois Bourgeois

14
$v = mt_rand() / mt_getrandmax();

如果您只需要保留小数点后一位(例如问题中的示例),只需对获取到的值使用round()函数即可...

$v = round( $v, 1 );

......或计算介于0和10之间的数字并除以10:

$v = mt_rand( 0, 10 ) / 10;

6
根据PHP文档,如果您使用的是PHP 7,则可以使用random_int生成一个加密安全的伪随机整数。
因此,这里有一个函数,利用它来生成两个数字之间的随机浮点数:
function random_float($min, $max) {
    return random_int($min, $max - 1) + (random_int(0, PHP_INT_MAX - 1) / PHP_INT_MAX );
}

虽然random_int()比mt_rand()更安全,但请记住它也会更慢。

之前的答案建议您使用PHP rand(),但实现很糟糕。我想改变我的答案,而不重复其他人已经说过的话,现在我们来到这里。


3
结果不会均匀分布,因为1.0的概率为0.5。此外,您只能获得0.1的分辨率。 - Francois Bourgeois
花了我一些时间。几年后。这样好吗? - ZeroZipZilch

2

试试这个

// Generates and prints 100 random number between 0.0 and 1.0 
$max = 1.0;
$min = 0.0;
for ($i = 0; $i < 100; ++$i)
{
    print ("<br>");
    $range = $max - $min;
    $num = $min + $range * (mt_rand() / mt_getrandmax());    
    $num = round($num, 2);
    print ((float) $num);
}

2
这个简单的解决方案如何:
abs(1-mt_rand()/mt_rand()) 

或者

/**
 * Generate Float Random Number
 *
 * @param float $Min Minimal value
 * @param float $Max Maximal value
 * @param int $round The optional number of decimal digits to round to. default 0 means not round
 * @return float Random float value
 */
function float_rand($Min, $Max, $round=0){
    //validate input
    if ($min>$Max) { $min=$Max; $max=$Min; }
        else { $min=$Min; $max=$Max; }
    $randomfloat = $min + mt_rand() / mt_getrandmax() * ($max - $min);
    if($round>0)
        $randomfloat = round($randomfloat,$round);

    return $randomfloat;
}

2
在使用他人的作品时,请始终引用您的来源。http://www.ivankristianto.com/php-snippet-code-to-generate-random-float-number/ 谢谢! - Pekka
1
代码中有一个错误: 这些行: if ( $min >$Max) { $min=$Max; $max=$Min; } 应该改为: if ( $Min >$Max) { $min=$Max; $max=$Min; } - Madcoe
此外,并不需要保证$Min < $Max - 交换它们会产生数学上相同的概率分布...... - Jollywatt
2
第一个解决方案无效。将两个独立的均匀分布随机变量相除会得到一个均匀比例分布(尽管计算机总是离散的;这是一种近似)。请参见https://en.wikipedia.org/wiki/Ratio_distribution。有1/4的概率返回一个大于1的数字(并且可以返回任何大小的数字,概率随数字的平方递减)。均匀比例分布不再是均匀分布。 - aphid

1

将其转换为浮点数*,然后除以getrandmax()


* 在 PHP 的任意类型转换规则中,似乎不需要进行强制类型转换。但在其他语言中可能需要。


3
规则并非随意制定。 - Darth Egregious
3
也许不是完全随意,但肯定是一系列事后临时补救的结果,导致了一个混乱不一致的规则集。 - Oliver Charlesworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接