Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigDecimal loses precision after multiplication

I'm getting a strange behaviour with BigDecimal in ruby. Why does this print false?

require 'bigdecimal'

a = BigDecimal.new('100')
b = BigDecimal.new('5.1')
c = a / b
puts c * b == a #false
like image 603
nmat Avatar asked Dec 12 '25 08:12

nmat


1 Answers

BigDecimal doesn't claim to have infinite precision, it just provides support for precisions outside the normal floating point ranges:

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

But BigDecimal values still have a finite number of significant digits, hence the precs method:

precs

Returns an Array of two Integer values.

The first value is the current number of significant digits in the BigDecimal. The second value is the maximum number of significant digits for the BigDecimal.

You can see things starting to go awry if you look at your c:

>> c.to_s
=> "0.19607843137254901960784313725E2"

That's a nice clean rational number but BigDecimal doesn't know that, it is still stuck seeing c as a finite string of digits.

If you use Rational instead, you'll get the results you're expecting:

>> a = Rational(100)
>> b = Rational(51, 10)
>> c * b == a
=> true

Of course, this trickery only applies if you are working with Rational numbers so anything fancy (such as roots or trigonometry) is out of bounds.

like image 74
mu is too short Avatar answered Dec 15 '25 14:12

mu is too short



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!