[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

BigDecimal Float worries

Henrik Horneber

10/1/2004 11:09:00 PM

Hi!

I stumbled over something while toying around with BigDecimal

require 'bigdecimal'
==>true

a = 2.12
==>2.12
b = BigDecimal.new(a.to_s).to_f
==>2.12
a == b
==>true
a = 20.12
==>20.12
b = BigDecimal.new(a.to_s).to_f
==>20.12
a == b
==>false
a.class == b.class
==>true
a.to_s == b.to_s
==>true

# in short
a == b
==>false # and then sometimes its true
a == b.to_s.to_f
==>true
b == b.to_s.to_f
==>false
#even though
b.class == b.to_s.to_f.class
==>true
a.class == b.class
==>true


seems a little strange to me.
what's going on? :)

Henrik

D:\>ruby -v
ruby 1.8.2 (2004-07-29) [i386-mswin32]






4 Answers

Henry T. So Jr.

10/2/2004 12:43:00 AM

0

On Sat, Oct 02, 2004 at 08:09:10AM +0900, Henrik Horneber wrote:
> seems a little strange to me.
> what's going on? :)
>
> Henrik
>
> D:\>ruby -v
> ruby 1.8.2 (2004-07-29) [i386-mswin32]

You are seeing what I consider a classic problem of computer
programming. Floating point numbers are usually represented in
computers using a format such as IEEE 754. Basically, there are so many
bits to represent the mantissa and so many bits for the exponent. The
rub is that everything is in binary. So what can be represented as an
exact decimal cannot always be represented exactly in binary (and
vice-versa). Conversion of two slightly different floating point
representations into a string for display may result in the same printed
value because the difference is so insignificant in decimal terms.

In school, we were taught never to compare floating point numbers
directly because of this. We were taught to compare them to see if they
were different by less than some threshold (which we generically called
"epsilon"). If the difference was less than epsilon then the numbers
were considered "equal" enough. The problem is that epsilon depends on
the application (i.e., depending on how much error the calculations were
willing to deal with).

This problem is also why things like the BigDecimal class are needed.
The BigDecimal class stores numbers with arbitrary precision in case the
error introduced by IEEE 754 and such formats is too significant in the
calculation.

Hope that wasn't more confusing...

Henry.


Henrik Horneber

10/2/2004 9:41:00 AM

0

Hi!

Henry T. So Jr. wrote:
> On Sat, Oct 02, 2004 at 08:09:10AM +0900, Henrik Horneber wrote:
>
>>seems a little strange to me.
>>what's going on? :)
>>
>>Henrik
>>
>>D:\>ruby -v
>>ruby 1.8.2 (2004-07-29) [i386-mswin32]
>
>
> You are seeing what I consider a classic problem of computer
> programming. Floating point numbers are usually represented in
> computers using a format such as IEEE 754. Basically, there are so many
> bits to represent the mantissa and so many bits for the exponent. The
> rub is that everything is in binary. So what can be represented as an
> exact decimal cannot always be represented exactly in binary (and
> vice-versa).
> Conversion of two slightly different floating point
> representations into a string for display may result in the same printed
> value because the difference is so insignificant in decimal terms.
>
> In school, we were taught never to compare floating point numbers
> directly because of this. We were taught to compare them to see if they
> were different by less than some threshold (which we generically called
> "epsilon"). If the difference was less than epsilon then the numbers
> were considered "equal" enough. The problem is that epsilon depends on
> the application (i.e., depending on how much error the calculations were
> willing to deal with).
>
> This problem is also why things like the BigDecimal class are needed.
> The BigDecimal class stores numbers with arbitrary precision in case the
> error introduced by IEEE 754 and such formats is too significant in the
> calculation.
>


Well yes, I was aware of that fact, that's why I was using BigDecimals
in the first place. I was _not_ aware of the fact, that
- turning a float to a string
- turning the string to a BigDecimal
- turning the BigDecimal to a float
generates such problems, just because strings and BigDecimals seemed a
'wider' type to me. Now that you mention it, it is kind of obvious that
there still are these problems, because of different representations.
Strange how such perceptions of 'wider' or 'more precise' can fool you...


Thanks!

Henrik


Robert Klemme

10/2/2004 10:41:00 AM

0


"Henrik Horneber" <ryco@gmx.net> schrieb im Newsbeitrag
news:415E787B.7050108@gmx.net...
> Well yes, I was aware of that fact, that's why I was using BigDecimals in
> the first place. I was _not_ aware of the fact, that
> - turning a float to a string
> - turning the string to a BigDecimal
> - turning the BigDecimal to a float
> generates such problems, just because strings and BigDecimals seemed a
> 'wider' type to me. Now that you mention it, it is kind of obvious that
> there still are these problems, because of different representations.
> Strange how such perceptions of 'wider' or 'more precise' can fool you...

Well, the weakest link in the chain is the crucial one and in this case it's
the float. So as long as the values are converted into a float once
somewhere in the process you can bet that == will fail at some point. :-)

Regards

robert

Henrik Horneber

10/2/2004 12:43:00 PM

0

Robert Klemme wrote:

>
> "Henrik Horneber" <ryco@gmx.net> schrieb im Newsbeitrag
> news:415E787B.7050108@gmx.net...
>
>> Well yes, I was aware of that fact, that's why I was using BigDecimals
>> in the first place. I was _not_ aware of the fact, that
>> - turning a float to a string
>> - turning the string to a BigDecimal
>> - turning the BigDecimal to a float
>> generates such problems, just because strings and BigDecimals seemed a
>> 'wider' type to me. Now that you mention it, it is kind of obvious
>> that there still are these problems, because of different
>> representations. Strange how such perceptions of 'wider' or 'more
>> precise' can fool you...
>
>
> Well, the weakest link in the chain is the crucial one and in this case
> it's the float. So as long as the values are converted into a float
> once somewhere in the process you can bet that == will fail at some
> point. :-)
>

This is what it boils down to, agreed. I guess I just can't see the
forrest because of all those trees.

Henrik