如何在Ruby中0.2 + rand(0.3)超过1?

时间:2014-08-13 16:09:45

标签: ruby

我试图调试Sonic Pi 2.0中的一个样本(Raspberry Pi上的SuperCollider的Ruby包装器)。我已经将问题代码缩小到这几行简单的Ruby:

loop do
  s = 0.2 + rand(0.3)
  e = s + 0.0625
  puts 's = ' + s.to_s + ', e = ' + e.to_s
  sleep 1
end

the documenation我希望每次循环都会被设置为0.2到0.5之间的值。但不,这是一个典型的结果:

==> Starting run 143

[Run 143, Time 0.0]
 +- s = 0.6204361822133666, e = 0.6829361822133666

[Run 143, Time 1.0]
 +- s = 0.2832891087607155, e = 0.3457891087607155

[Run 143, Time 2.0]
 +- s = 0.4914545052249532, e = 0.5539545052249533

[Run 143, Time 3.0]
 +- s = 0.8560154313773802, e = 0.9185154313773802

[Run 143, Time 4.0]
 +- s = 1.1902533463314418, e = 1.2527533463314418

s的高值来自哪些想法?

3 个答案:

答案 0 :(得分:7)

这是因为您传递的值小于1 max。 Ruby实际上对参数执行了abs.to_i,如果它的计算结果为零,rand将返回0到1之间的数字。

示例:

> rand(0.3)   # 0.3.abs.to_i evaluates to 0
=> 0.5406754757491508

有关详细信息,请参阅the docs。他们甚至对这个特定问题发表评论:

  

允许使用最大值的负值或浮点值,但可能会产生令人惊讶的结果。

如果您想获得0到0.3之间的数字,请执行以下操作:

rand * 0.3

或者正如维克多指出的那样,你可以使用Random.rand按预期工作:

Random.rand(0.3)   # this will always be >= 0 and < 0.3

答案 1 :(得分:1)

您在rand上使用的最大参数的行为与预期的不同:

它在文档中说:

  

当max.abs大于或等于1时,rand返回a   伪随机整数大于或等于0且小于   max.to_i.abs。

所以rand(0.3)可以得到0.9这样的值,因此

答案 2 :(得分:1)

rand(内核#rand,你正在使用的那个)和Random#rand(你链接的文档中的那个)之间存在差异。

您应该在代码中使用Random#rand。