当最小值和最大值为正时,为什么rand()会返回负值?

时间:2009-10-19 09:46:49

标签: php random

我有一段简单的PHP代码,需要创建一个随机数。但是,即使输入始终为正,有时也会返回负输出。

这是我的调试代码:

$debt = rand($this->gdp * 0.02, $this->gdp * 0.17);
echo "<p>GDP: ".$this->gdp." rand(".$this->gdp * 0.02."  , ".$this->gdp * 0.17.") = <strong>".$debt."</strong></p>";

以下是输出示例:

GDP: 219254674605 rand(4385093492.1 , 37273294682.85) = 75276999

GDP: 345015694865 rand(6900313897.3 , 58652668127.05) = -1636353016

GDP: 90445390920 rand(1808907818.4 , 15375716456.4) = -165604705

GDP: 3412849650 rand(68256993 , 580184440.5) = 347516196

GDP: 2939111315 rand(58782226.3 , 499648923.55) = 119181875

GDP: 26369065 rand(527381.3 , 4482741.05) = 3632416

GDP: 215838135 rand(4316762.7 , 36692482.95) = 28784811

GDP: 511763530 rand(10235270.6 , 86999800.1) = 39954394

GDP: 42416245 rand(848324.9 , 7210761.65) = 3974882

GDP: 75090235 rand(1501804.7 , 12765339.95) = 5201966

那么为什么两个正数的rand()给出负回报?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:14)

因为您在参数中看到整数溢出。

根据rand() documentation,它需要两个int值作为参数。在32位机器上,这些也是32位(至少对于PHP)。所以当你传递大于2 31 - 1的参数时,它们会溢出并再次从-2 31 开始。

显然,如果你需要更大的值,你必须自己编码。虽然只是从两个32位数字创建一个64位数字按预期工作,但您不能简单地使用最大值进行模运算,因为这会使分布出现偏差。为了更好地实现如何在0和某个上限之间生成均匀分布的随机整数,您可以查看java.util.Random.nextInt(int)并相应地调整64位整数。

mt_rand()虽然通常是随机数的一个很好的选择,因为它使用MT19937而不是一个差的LCG,但这里也没有帮助,因为它的参数也是int


如果您不需要最终选择所有可能的值,则可能需要考虑的另一个选项:

  • 通过调用

    生成0到1之间的随机浮点值
    $rnd = mt_rand() / (double)mt_getrandmax()
    
  • 确定所需的数字范围:

    $min = $this->gdp * 0.02;
    $max = $this->gdp * 0.17;
    $range = $max - $min;
    
  • 将此乘以先前获得的随机浮点值并添加最小值:

    $value = $min + $range * $rnd
    
  • 现在,您在所选边界之间有一个随机值。它大致均匀分布,尽管在相邻随机数之间存在离散步长,因为您在大量位上拉伸32位随机性。如果这对您没有问题,请继续。

答案 1 :(得分:1)

Rand作为参数,并返回integers。整数(在PHP中)的最大范围通常为2 ** 32。

你的双参数大于此值,当它们转换为整数时会导致integer overflow