Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is BigDecimal returning a weird value?

I am writing code that will deal with currencies, charges, etc. I am going to use the BigDecimal class for math and storage, but we ran into something weird with it.

This statement:

1876.8 == BigDecimal('1876.8')

returns false.

If I run those values through a formatting string "%.13f" I get:

"%.20f" % 1876.8 => 1876.8000000000000
"%.20f" % BigDecimal('1876.8') => 1876.8000000000002

Note the extra 2 from the BigDecimal at the last decimal place.

I thought BigDecimal was supposed to counter the inaccuracies of storing real numbers directly in the native floating point of the computer. Where is this 2 coming from?

like image 796
Tilendor Avatar asked Apr 23 '09 18:04

Tilendor


People also ask

How accurate is BigDecimal?

This limits it to 15 to 17 decimal digits of accuracy. BigDecimal can grow to any size you need it to. Double operates in binary which means it can only precisely represent numbers which can be expressed as a finite number in binary. For example, 0.375 in binary is exactly 0.011.

How do I stop rounding in BigDecimal?

56 if you use BigDecimal newValue = myBigDecimal. setScale(2, RoundingMode. DOWN); " This statement is true for HALF_DOWN not for DOWN mode.

What can I use instead of BigDecimal?

If you need to use division in your arithmetic, you need to use double instead of BigDecimal.

Why should we use BigDecimal?

The BigDecimal class provides operations on double numbers for arithmetic, scale handling, rounding, comparison, format conversion and hashing. It can handle very large and very small floating point numbers with great precision but compensating with the time complexity a bit.


1 Answers

It won't give you as much control over the number of decimal places, but the conventional format mechanism for BigDecimal appears to be:

a.to_s('F')

If you need more control, consider using the Money gem, assuming your domain problem is mostly about currency.

gem install money
like image 53
JasonTrue Avatar answered Sep 25 '22 22:09

JasonTrue