【问题标题】:Why would rand() return a negative value when min and max values are positive?当最小值和最大值为正时,为什么 rand() 会返回负值?
【发布时间】:2010-12-07 22:49:43
【问题描述】:

我有一段简单的 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() 会产生负回报?

任何帮助将不胜感激!

【问题讨论】:

    标签: php random


    【解决方案1】:

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

    根据rand() documentation,它需要两个int 值作为参数。在 32 位机器上,它们也是 32 位的(至少对于 PHP 而言)。因此,当您传递大于 231 - 1 的参数时,它们会溢出并再次从 -231 开始。

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

    mt_rand() 虽然通常是随机数的不错选择,因为它使用 MT19937 而不是糟糕的 LCG,但在这里也无济于事,因为它的参数也是 ints。


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

    • 通过调用生成一个介于 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 位随机性扩展到更多位。不过,如果这对您来说没问题,请继续。

    【讨论】:

    • 考虑使用 mt_rand() 代替
    • Psytronic:究竟改变了什么de.php.net/manual/en/function.mt-rand.php 表明 mt_rand 也使用 int 参数。
    • 我只是在 rand 描述下面的注释: 注意:在某些平台(例如 Windows)上,getrandmax() 仅为 32768。如果您需要大于 32768 的范围,请指定 min 和max 将允许您创建比这更大的范围,或者考虑使用 mt_rand() 代替。
    • Psytronic:好的,我可以解决 OP 问题的最后一个选项是使用 mt_rand() 来确定。 :-)
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-10
      • 2020-09-06
      • 2015-05-19
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      相关资源
      最近更新 更多