首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Ruby BigDecimal健全性检查(浮点newb)

Ruby BigDecimal健全性检查(浮点newb)
EN

Stack Overflow用户
提问于 2010-06-15 02:04:30
回答 1查看 7.4K关注 0票数 21

我对Ruby BigDecimal类型(即使具有不同的精度和小数位数长度)应该准确计算的理解是正确的,还是应该预期到浮点恶作剧?

我在Rails应用程序中的所有值都是BigDecimal类型,并且我看到了一些错误(它们的小数长度不同),希望这只是我的方法而不是我的对象类型。

EN

回答 1

Stack Overflow用户

发布于 2010-06-15 04:56:14

在使用浮点运算时,有两个常见的陷阱。

的第一个问题是浮点数具有固定的精度。在实践中,这要么是1)对你来说没有问题,要么是2)灾难性的,或者3)介于两者之间。请考虑以下几点:

代码语言:javascript
复制
# float
1.0e+25 - 9999999999999999900000000.0
#=> 0.0

# bigdecimal
BigDecimal("1.0e+25") - BigDecimal("9999999999999999900000000.0")
#=> 100000000

精度差一亿!很严肃,对吧?

但精度误差仅为原始值的0.000000000000001%左右。这真的是由你来决定这是不是一个问题。但是这个问题可以通过使用BigDecimal来解决,因为它具有任意精度。您唯一的限制是Ruby可以使用的内存。

的第二个问题是,浮点数不能准确地表示所有分数。特别是,它们在小数方面有问题,因为Ruby (和大多数其他语言)中的浮点是二进制浮点。例如,十进制分数0.2是一个永远重复的二进制分数(0.001100110011...)。无论精度是多少,这永远不能以二进制浮点数的形式准确存储。

当你对数字进行四舍五入时,这会产生很大的差异。考虑一下:

代码语言:javascript
复制
# float
(0.29 * 50).round
#=> 14  # not correct

# bigdecimal
(BigDecimal("0.29") * 50).round
#=> 15  # correct

BigDecimal可以精确地描述小数。然而,也有一些分数不能用小数精确地描述。例如,1/9是一个永远重复的小数(0.1111111111111...)。

同样,当你舍入一个数字时,这会咬你一口。考虑一下:

代码语言:javascript
复制
# bigdecimal
(BigDecimal("1") / 9 * 9 / 2).round
#=> 0  # not correct

在这种情况下,使用十进制浮点仍然会产生舍入误差()。

一些结论:

如果您使用小数进行计算,

  • 小数浮点数将非常棒(对于example).
  • Ruby's BigDecimal,如果您需要任意精度浮点数,并且并不真正关心它们是十进制浮点还是二进制浮点数,则它也很有效。
  • 如果您处理(科学)数据,您通常需要处理固定精度的数字;Ruby的内置浮点数可能就足够了。
  • 您永远不能期望任何类型的浮点数的算术在所有情况下都是精确的。
票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3039650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档