为什么我的BigDecimal对象初始化有意外的舍入错误? [英] Why are my BigDecimal objects initialized with unexpected rounding errors?

查看:152
本文介绍了为什么我的BigDecimal对象初始化有意外的舍入错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ruby 2.2.0中,为什么:

  BigDecimal.new(34.13985572755337,9)
code>

等于 34.0 但是

  BigDecimal.new(34.13985572755338,9)

等于 34.1398557



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

解决方案

用字符串初始化而不是浮动



用Floats无法获得可靠的行为。你犯的错误是用Float值而不是String值来初始化你的BigDecimals,这在一开始就引入了一些不准确的地方。例如,在我的64位系统上:

  float1 = 34.13985572755337 
float2 = 34.13985572755338

#如果你的Float不能正确地
#表示,你也可以在这里使用字符串文字。例如:

#BigDecimal.new(34.13985572755337,9)

#会更安全,但是Float#to_s可以和提供的语料一起工作。
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
#=>真正的

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


In Ruby 2.2.0, why does:

BigDecimal.new(34.13985572755337, 9)

equal 34.0 but

BigDecimal.new(34.13985572755338, 9)

equal 34.1398557?

Note that I am running this on a 64 bit machine.

解决方案

Initialize with Strings Instead of Floats

In general, you can't get reliable behavior with Floats. You're making the mistake of initializing your BigDecimals with Float values instead of String values, which introduces some imprecision right at the beginning. For example, on my 64-bit system:

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

This is one of those cases where the internal representation of the arguments matter. Therefore, your mileage will vary depending on how you initialize your object.

这篇关于为什么我的BigDecimal对象初始化有意外的舍入错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆