我BigDecimal
在红宝石中遇到了一种奇怪的行为。为什么这个打印错误?
require 'bigdecimal'
a = BigDecimal.new('100')
b = BigDecimal.new('5.1')
c = a / b
puts c * b == a #false
我BigDecimal
在红宝石中遇到了一种奇怪的行为。为什么这个打印错误?
require 'bigdecimal'
a = BigDecimal.new('100')
b = BigDecimal.new('5.1')
c = a / b
puts c * b == a #false
BigDecimal 并不声称具有无限精度,它只是提供对正常浮点范围之外的精度的支持:
BigDecimal
为非常大或非常精确的浮点数提供类似的支持。
但是 BigDecimal 值仍然具有有限数量的有效数字,因此该precs
方法:
前言
返回两个整数值的数组。
第一个值是 BigDecimal 中的当前有效位数。第二个值是 BigDecimal 的最大有效位数。
如果您查看以下内容,您会发现事情开始出错c
:
>> c.to_s
=> "0.19607843137254901960784313725E2"
这是一个很好的干净有理数,但 BigDecimal 不知道,它仍然被c
视为有限的数字串。
如果您改用 Rational,您将获得您期望的结果:
>> a = Rational(100)
>> b = Rational(51, 10)
>> c * b == a
=> true
当然,这个技巧只适用于有理数,所以任何花哨的东西(如根或三角函数)都超出了界限。
这是正常行为,一点也不奇怪。
BigDecimal
不保证无限精度,它允许您指定任意精度,这不是一回事。100/5.1
无法使用浮点内部表示以完全精度表示该值。使用多少位无关紧要。
“大理性”方法可以实现它 - 但不会让您访问某些功能,例如平方根。
请参阅http://ruby-doc.org/core-1.9.3/Rational.html
# require 'rational' necessary only in Ruby 1.8
a = 100.to_r
b = '5.1'.to_r
c = a / b
c * b == a
# => true