我有一段简单的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()
给出负回报?
非常感谢任何帮助!
答案 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。