ruby - 为什么我的 BigDecimal 对象初始化时出现意外舍入错误?

标签 ruby floating-point rounding bigdecimal floating-point-precision

在 Ruby 2.2.0 中,为什么:

BigDecimal.new(34.13985572755337, 9)

等于 34.0 但是

BigDecimal.new(34.13985572755338, 9)

等于 34.1398557?

请注意,我在 64 位机器上运行它。

最佳答案

用字符串而不是 float 初始化

一般来说,您无法通过 float 获得可靠的行为。您错误地使用 Float 值而不是 String 值初始化 BigDecimals,这在一开始就引入了一些不精确性。例如,在我的 64 位系统上:

float1 = 34.13985572755337
float2 = 34.13985572755338

# You can use string literals here, too, if your Float can't be properly
# represented. For example:
#
#    BigDecimal.new("34.13985572755337", 9)
#
# would be safer, but Float#to_s works fine with the provided corpus.
bd1 = BigDecimal.new(float1.to_s, 9)
bd2 = BigDecimal.new(float2.to_s, 9)

bd1.to_s
#=> "0.3413985572755337E2"
bd2.to_s
#=> "0.3413985572755338E2"

bd1.to_f == float1
#=> true
bd2.to_f == float2
#=> true

这是参数的内部表示很重要的情况之一。因此,您的里程将根据您初始化对象的方式而有所不同。

关于ruby - 为什么我的 BigDecimal 对象初始化时出现意外舍入错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28295583/

相关文章:

ruby - 我可以继续使用 MongoDB v2.2.0rc 使用 1.6.4 Ruby 驱动程序吗?

ruby - Chef Run(Omnibus 安装)中的 PATH 在哪里强制执行/配置?

ruby-on-rails - 请求时生成 imagemagick/carrierwave 缩略图

Java:四舍五入到任意值

python - 如何将 float 舍入为缩放整数?

ruby - 将带有修饰符的字符串转换为 Ruby 正则表达式

floating-point - 使用 IEEE 754 32 位浮点格式可以实现的最接近 1/3 的值是多少?

postgresql 四舍五入函数

php - 将逗号作为小数点的数字转换为 float

PHP 舍入问题(5.2.3)?