Issue with precision of Ruby math operations

后端 未结 3 505
心在旅途
心在旅途 2021-01-23 22:18

Do you know how to fix the following issue with math precision?

p RUBY_VERSION # => \"1.9.1\"
p 0.1%1 # => 0.1
p 1.1%1 # => 0.1
p 90.0%1 # => 0.0
p 9         


        
相关标签:
3条回答
  • 2021-01-23 22:36

    Writing 0.1 into a floating point will always result in rounding errors. If you want 'precise' decimal representation, you should use the Decimal type.

    0 讨论(0)
  • 2021-01-23 22:47

    Big Decimal


    As the man said;

    Squeezing infinitely many real numbers into a finite number of bits requires an approximate representation.


    I have however had great success using the BigDecimal class. To quote its intro

    Ruby provides built-in support for arbitrary precision integer arithmetic. For example:

    42**13 -> 1265437718438866624512

    BigDecimal provides similar support for very large or very accurate floating point numbers.


    Taking one of your examples;

    >> x = BigDecimal.new('900.1')
    => #<BigDecimal:101113be8,'0.9001E3',8(8)>
    >> x % 1
    => #<BigDecimal:10110b498,'0.1E0',4(16)>
    >> y = x % 1
    => #<BigDecimal:101104760,'0.1E0',4(16)>
    >> y.to_s
    => "0.1E0"
    >> y.to_f
    => 0.1
    


    As you can see, ensuring decent precision is possible but it requires a little bit of effort.

    0 讨论(0)
  • 2021-01-23 22:53

    This is true of all computer languages, not just Ruby. It's a feature of representing floating point numbers on binary computers:

    What Every Computer Scientist Should Know About Floating Point Arithmetic

    0 讨论(0)
提交回复
热议问题