Topic: Force calculation result to BigDecimal

Hi all,

I'm doing some complex math which I need to be based on BigDecimal accuracy (not Float).  It seems that ruby defaults to Float when there's a mixture of type in there, e.g.

irb(main):001:0> require 'bigdecimal'
=> true
irb(main):002:0> a = 5.123
=> 5.123
irb(main):003:0> b = BigDecimal("6.789")
=> #<BigDecimal:8b4c0,'0.6789E1',8(8)>
irb(main):004:0> c = a * b
=> 34.780047
irb(main):005:0> c.class
=> Float

Is there a way I can force a BigDecimal outcome.

One way I guess would work is to make sure all args in the calculation are BigDecimal, but that's a bit tiresome.  For a start, I'd have to type check each arg and convert to BigDecimal if it was not BigDecimal - that's gotta be slow...

On a related note, how do I initalize a BigDecimal from a Float (without converting to string first).  How could I extend BigDecimal for this?


Thanks,



Rob

Re: Force calculation result to BigDecimal

rob99 wrote:

Hi all,
One way I guess would work is to make sure all args in the calculation are BigDecimal, but that's a bit tiresome.  For a start, I'd have to type check each arg and convert to BigDecimal if it was not BigDecimal - that's gotta be slow...

Hi Rob,

The assumption seems to be that something_inaccurate * something_accurate will always be inaccurate, that's why a float is returned.

rob99 wrote:

On a related note, how do I initalize a BigDecimal from a Float (without converting to string first).  How could I extend BigDecimal for this?

The good news is this part is already done for you via the "to_d" method. If you poke around the docs a bit you'll find more info on the BigDecimal class.

require 'bigdecimal'
require 'bigdecimal/util'

a = 5.123.to_d   #=> #<BigDecimal:2dc042c,'0.5123E1',8(8)>
b = "6.789".to_d #=> #<BigDecimal:2dbde20,'0.6789E1',8(8)>
c = a * b        #=> #<BigDecimal:2db93fc,'0.34780047E2',12(24)>

Re: Force calculation result to BigDecimal

Thanks Chap,

Problem is, these a user input numbers, so I user might put in a Fixnum, which has no .to_d.

I suppose I could add a to_d to Fixnum myself....

Thanks again....