7

我想在 ruby​​ 中用 0.0001 步从 0.0001 数到 1。我写了这段代码,但它进入了一个无限循环。不知何故,解释器做了错误的总结。

x = 0.0001
while x != 1.0
  puts x
  x = x + 0.0001
end

这是它给出的前 10 个值:

0.0001
0.0002
0.00030000000000000003
0.0004
0.0005
0.0006000000000000001
0.0007000000000000001
0.0008000000000000001
0.0009000000000000002
0.0010000000000000002

它应该是 0.0001、0.0002、0.0003 等......我怎样才能让它工作?谢谢!

4

6 回答 6

16

试试这个:

0.0001.step(1, 0.0001).each { |i| puts i }

编辑:您应该使用该Float#step方法,因为它可以保护您免受浮点运算的怪异。Float#step将负责增加值并以防浮动的方式与限制进行比较。更多信息请查看官方文档Float#step

于 2011-12-16T14:37:54.500 回答
2

问题是由于二进制存储和操作,ruby 中的实数不能准确表示。我会这样做

x = 1
while x < 10000
    puts (x/10000).round(4)
    x += 1
end
于 2011-12-16T14:38:11.337 回答
1

而不是x != 1.0,放x < 1.0。这至少可以确保你的循环结束。

像运行我们所有现代计算机的二进制系统不能(容易地)表示分数,尤其是不能用十进制精确表示的分数。这就是你应该有的奇怪数字出现的地方.0003。这是数字如何在内部表示的人工制品。

有些语言比其他语言更擅长处理数字和准确性,因此如果数字的准确性很重要,您要么需要使用不同的语言,要么使用为您处理数字事物(有效数字等)的库,或者您需要在每一步通过适当的舍入等自行处理。

于 2011-12-16T14:34:49.850 回答
0

浮点数并不完全准确Wikipedia Floating Point 文章

如果您必须有干净的 x,我建议您使用整数并在使用该值之前除以 1000。如果您不关心一点点噪音,您可以将 while x != 1.0 更改为 while x < 1.0

于 2011-12-16T14:39:01.363 回答
0

您所看到的是由于浮点数的二进制表示。这会影响所有计算机编程语言。有关更多详细信息,请参阅每位计算机科学家应该了解的浮点运算知识

您可以做的是在打印时将其四舍五入到适当的位数,或者如 goiele 发现的那样,使用step

0.0001.step(1, 0.0001).each do |i|
  puts i
end
于 2011-12-16T14:48:24.177 回答
0
1.step(10000, 1).each { |x| puts "%f" % (x / 10000.0).round(4) }
于 2011-12-16T15:06:19.993 回答