2009-11-30 52 views

回答

0

看起来像一个简单的案例binary floating point imprecision。在一台机器上,你可以得到40.499999999到40;在另一台机器上,你得到40.500000000001,其中四舍五入41.

如果你需要确切的数字,那么你不应该使用二进制浮点数。您可以使用定点十进制或十进制浮点。

编辑:你正在使用BigDecimal,你说。为什么不通过使用#round然后#to_i来避免任何转换浮动? (或者#floor#ceil代替#round ......它没有清除您的目标是什么。)

b = BigDecimal.new("40.5") 
print b.round.to_i # => 41 
+0

我保持这个例子非常简单,但是这个数字实际上来自数据库中的BigDecimal字段。我相信它提到的浮点问题只是不确定为什么它被视为浮点数。您仍然遇到以下问题: “%.0f”%BigDecimal(“40.5”)和“%.0d”%BigDecimal(“40.5”) – tsdbrown 2009-12-01 15:47:06

+0

这是因为这里的BigDecimals正在转换为浮动(通过#to_f)在进行格式化操作之前。 – ScottJ 2009-12-01 23:18:37

+0

如果不清楚,我编辑了我的上面的答案,以专门解决BigDecimal的问题。 – ScottJ 2009-12-01 23:21:48

2

有关使用.round,而不是如何呢? Rails甚至增强了它,以便您可以指定精度(see API doc)。

+0

尽管40.5.round(0)给出了41.0,但是我们首先想要做到这一点,这非常烦人。我从API文档看到.round现在接受nil,只剩下41和0之后。我敢肯定,在我们正在使用的Rails版本中,round(nil)抛出错误。为了解决它,我们首先围绕它(0),然后应用字符串格式。谢谢。 – tsdbrown 2009-12-01 15:37:41

+0

我不明白tsdbrown的评论。浮轮#轮不会有任何争论。 BigDecimal#round指定小数位数和ruby-doc.org作为合法参数不显示nil。 BigDecimal也不区分41.0和41. – ScottJ 2009-12-01 23:15:35

1

使用%0.0克代替

1

ScottJ的答案并不能解释你的问题 - 40.5是精确表示二进制文件。可能发生的情况是:Windows'printf'减半,“而Ubuntu的printf”则减半。“