Enter the 36 chambers of infrastructure wu-tang

Wednesday, March 26, 2008

BigDecimal: mostly acceptable alternative to Float

I forgot to mention in yesterday's extended whine about Ruby floating point that there is a package in the standard library called BigDecimal that is a mostly good alternative to the normal Float class.  Here is the simplest way to use it:

require "bigdecimal"
require "bigdecimal/util"

The second line adds a new method, to_d, to String, Float, and Rational.  Back to my annoying example of broken floating point math:

>> require "bigdecimal"
=> true
>> require "bigdecimal/util"
=> true
>> (9.54 / 0.001)
=> 9540.0
>> (9.54 / 0.001).to_i
=> 9539
>> (9.54 / 0.001).to_d.to_i
=> 9540

Well, almost.  BigDecimal slows things down a bit compared to Float and the extra work (the remembering part, not the typing part) of adding to_d is effort that shouldn't be required.  I should be clear here that I have no problem with BigDecimal itself.  BigDecimal is extremely useful, as are the extended precision libraries for other languages.  No, the problem remains that, even though the Ruby Core team could implement a reasonable compromise in Float so it behaves consistently, they refuse to.

1 comment:

David Sinclair said...

Hi, I totally agree with everything you've written regarding this issue. I started implementing the Brent-Salamin algorithm(to calculate decimals of pi) and ran into similar problems. The general attitude against these problems are very similar to those in the early 90's with unix geeks refusing to use anything "graphical". Instead of doing anything about it people just treat you as an idiot when it's VERY clearly an issue that needs to be solved not buried.

Sincerely

David Sinclair