我想知道使用Ruby rand 内核函数在闭区间内获取伪随机浮点数的最佳方法(请不要随机模块)。
举一个例子,我将使用闭区间 [0.0,7.7] (区间内包含0.0和7.7),但任何其他浮动区间也应该有效。
对于区间[0.0,7.7],下一个解决方案无效:
rand * 7.7
为什么?
如果在没有参数的情况下调用 rand ,则会得到一个大于或等于0.0且小于1.0的伪随机浮点数。那么以前的解决方案可以给我们的浮点数范围是多少?
rand 将返回[0.0,0.9999999 ...]
范围内的伪随机浮点数0.0 * 7.7
=> 0.0 # Correct!
0.9999999 * 7.7
=> 7.69999923 # Incorrect!
间隔与[0.0,7.7]不匹配。
有谁知道这个问题的优雅解决方案?
谢谢!
答案 0 :(得分:4)
有一个Random
课可以做你想做的事:
generator = Random.new # You need to instance it
generator.rand 0.0..7.7
(文件说明将考虑0.0..7.7和0.0 ... 7.7之间的差异。)
在将来的1.9.3中,您可以将范围传递给Kernel#rand
和Random.rand
(您已经可以在预览版中执行此操作)。
答案 1 :(得分:0)
根据您需要的精度位数,您可以使用圆形均匀逼近捕捉到边缘的边界边界。希望这会有所帮助。
以下是Wikipedia
中的文字下半场甚至是一个平局规则,甚至更少偏见 圆半到均匀,即
如果y的分数是0.5,则q是最接近y的偶数。 因此,例如,+ 23.5变为+ 24,+ 22.5变为+ 22,变为-22.5 -22,-23.5变为-24。
此方法还对称地处理正值和负值, 因此,如果原始数字是,则没有整体偏差 正面或负面,概率相等。此外,对大多数人来说 合理的y值分布,预期(平均)值 四舍五入的数字基本上与原始数字相同 数字,即使后者都是正数(或全部为负数)。 但是,这条规则仍然会带来积极的偏见 数字(包括零),以及奇数的负偏差。
圆形到最近方法的这种变体也称为无偏 四舍五入(模糊地,有点滥用),收敛四舍五入, 统计学家的舍入,荷兰舍入,高斯舍入,或 银行家的四舍五入。这被广泛用于簿记。
这是IEEE 754计算功能中使用的默认舍入模式 和运营商。
答案 2 :(得分:0)
我会做这样的事情:
Fineness = 2**64
puts rand(Fineness+1)*7.7/Fineness
每当rand
返回其最大可能值时,您将得到Fineness*7.7/Fineness
,其结果完全等于7.7(但我不完全确定这种情况总是如此,因为浮点数不准确)
只要Fineness中的位数比计算机上的double多,我相信您不会发现结果分布有任何异常。
答案 3 :(得分:0)
怎么样:
(兰特/ 0.9999999999999999 ...)* 7.7
基本上,将随机数标准化为最大可能的随机数。这样你就可以创建范围[0..1]。
但是,我不确定如何获得最大数量,在ruby中小于1.0。
答案 4 :(得分:0)
你为什么需要这个?我不知道需要将其作为真正的单精度或双精度数的情况。另一方面,在某些情况下,您可能需要0.0到7.7之间的数字,增量为0.1。在这种情况下,你可以使用成熟的技术从0到77然后除以10。