Ruby doesn't know how to multiply

Hello,

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

I don't know if this is a bug. Please let me know. By the way i´m on
ruby 1.8.5. I'll give it a try on 1.8.6 and let you know.

Thanks,
Roberto Prado.

I thingh that it is a bug

···

2007/6/21, rjprado@gmail.com <rjprado@gmail.com>:

Hello,

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

I don't know if this is a bug. Please let me know. By the way i´m on
ruby 1.8.5. I'll give it a try on 1.8.6 and let you know.

Thanks,
Roberto Prado.

--
Juan Pedro Meriño Diaz
Ing de Sistema CURN

Hello,

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

I don't know if this is a bug. Please let me know. By the way i?m on
ruby 1.8.5. I'll give it a try on 1.8.6 and let you know.

% irb

"%2.40f" % (14.95 * 0.6)

=> "8.9699999999999988631316227838397026062012"

"%2.40f" % 8.97

=> "8.9700000000000006394884621840901672840118"

Thanks,
Roberto Prado.

--Greg

···

On Fri, Jun 22, 2007 at 04:25:04AM +0900, rjprado@gmail.com wrote:

It's not a bug. It's the way floating point arithmetic works, and is
true for *most* programming languages.

http://docs.sun.com/source/806-3568/ncg_goldberg.html

···

On 6/21/07, rjprado@gmail.com <rjprado@gmail.com> wrote:

Hello,

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

I don't know if this is a bug. Please let me know. By the way i´m on
ruby 1.8.5. I'll give it a try on 1.8.6 and let you know.

This happens in all languages that use floating point to represent decimal numbers (you will get precisely the same result in C or Javascript or Perl, for instance). Floating-point arithmetic is only approximate, so the result does not _exactly_ equal 8.97, even though it is very close.

Because of this, when using floating-point arithmetic, testing for exact equality is impractical. The best you can do is test whether the result is within some interval (epsilon) of the expected result:

( ( 14.95 * 0.6 ) - 8.97 ).abs < 1e-6

(Here, we've chosen 1e-6 as our epsilon, which is arbitrary but probably "small enough" in this case. For mathematically intensive code, you may need to be more careful.)

Although floating-point is the default for Ruby, you do have the option of using a different representation of numbers for which arithmetic is exact, although it will not be as fast. One such option is the Rational class in Ruby's standard library, which represents numbers as fractions rather than floating-point numbers.

-mental

···

On Fri, 22 Jun 2007 04:25:04 +0900, "rjprado@gmail.com" <rjprado@gmail.com> wrote:

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

Yes, you are all right. It's a common problem. I have confirmed this
by doing the same thing on java. Thank you all for your fast replies.

Greetings,
Roberto Prado.

···

On Jun 21, 3:21 pm, "rjpr...@gmail.com" <rjpr...@gmail.com> wrote:

Hello,

Dear friends, today I have stumbled into a really weird problem. Try
typing this on irb:

14.95 * 0.6 == 8.97

Ruby says it's false!

I don't know if this is a bug. Please let me know. By the way i´m on
ruby 1.8.5. I'll give it a try on 1.8.6 and let you know.

Thanks,
Roberto Prado.

It's not. It's a typical floating point error:

James Edward Gray II

···

On Jun 21, 2007, at 2:30 PM, juan pedro meriño wrote:

I thingh that it is a bug

thank you!

···

2007/6/21, MenTaLguY <mental@rydia.net>:

On Fri, 22 Jun 2007 04:25:04 +0900, "rjprado@gmail.com" <rjprado@gmail.com> > wrote:
> Dear friends, today I have stumbled into a really weird problem. Try
> typing this on irb:
>
> 14.95 * 0.6 == 8.97
>
> Ruby says it's false!

This happens in all languages that use floating point to represent decimal
numbers (you will get precisely the same result in C or Javascript or Perl,
for instance). Floating-point arithmetic is only approximate, so the result
does not _exactly_ equal 8.97, even though it is very close.

Because of this, when using floating-point arithmetic, testing for exact
equality is impractical. The best you can do is test whether the result is
within some interval (epsilon) of the expected result:

( ( 14.95 * 0.6 ) - 8.97 ).abs < 1e-6

(Here, we've chosen 1e-6 as our epsilon, which is arbitrary but probably
"small enough" in this case. For mathematically intensive code, you may
need to be more careful.)

Although floating-point is the default for Ruby, you do have the option of
using a different representation of numbers for which arithmetic is exact,
although it will not be as fast. One such option is the Rational class in
Ruby's standard library, which represents numbers as fractions rather than
floating-point numbers.

-mental

--
Juan Pedro Meriño Diaz
Ing de Sistema CURN

And if you are using test/unit then use the assertion method
assert_in_delta()

- nasir

···

On 6/21/07, MenTaLguY <mental@rydia.net> wrote:

On Fri, 22 Jun 2007 04:25:04 +0900, "rjprado@gmail.com" <rjprado@gmail.com> > wrote:
> Dear friends, today I have stumbled into a really weird problem. Try
> typing this on irb:
>
> 14.95 * 0.6 == 8.97
>
> Ruby says it's false!

This happens in all languages that use floating point to represent decimal
numbers (you will get precisely the same result in C or Javascript or Perl,
for instance). Floating-point arithmetic is only approximate, so the result
does not _exactly_ equal 8.97, even though it is very close.

Because of this, when using floating-point arithmetic, testing for exact
equality is impractical. The best you can do is test whether the result is
within some interval (epsilon) of the expected result:

( ( 14.95 * 0.6 ) - 8.97 ).abs < 1e-6

(Here, we've chosen 1e-6 as our epsilon, which is arbitrary but probably
"small enough" in this case. For mathematically intensive code, you may
need to be more careful.)

Although floating-point is the default for Ruby, you do have the option of
using a different representation of numbers for which arithmetic is exact,
although it will not be as fast. One such option is the Rational class in
Ruby's standard library, which represents numbers as fractions rather than
floating-point numbers.

-mental

Yes, you are all right. It's a common problem. I have confirmed this
by doing the same thing on java. Thank you all for your fast replies.

I tried this in Delphi, smalltalk and oracle SQL and got the correct
result.

C# and visual C++ seem to it to be false.

This is most perplexing.

···

--
Posted via http://www.ruby-forum.com/\.

MenTaLguY:

The best you can do is test whether the result is
within some interval (epsilon) of the expected result:

( ( 14.95 * 0.6 ) - 8.97 ).abs < 1e-6

(Here, we've chosen 1e-6 as our epsilon, which is arbitrary but
probably "small enough" in this case. For mathematically intensive
code, you may need to be more careful.)

Any particular reason against using Float::EPSILON here? :slight_smile:

Maybe Float#== could simply be extended to consider the above? That
would most probably open another can of worms, though, and extending
Float#<=> would open yet another, I guess.

-- Shot

···

--
I'm not much of a kernel hacker, but a quick (and not very efficient,
granted) fix could be to make the offset an extern variable, yes?
That would force the compiler to fall back on the basic "your gun,
your foot, your choice" memory model. -- jtv, LKML

You are rigth James, but you can better reponse why is a floating point
error?

Hi,

···

In message "Re: Ruby doesn't know how to multiply" on Fri, 22 Jun 2007 05:57:48 +0900, Lloyd Linklater <lloyd@2live4.com> writes:

I tried this in Delphi, smalltalk and oracle SQL and got the correct
result.

Interesting. There are a few ways to get the "correct" result.

  * fixed point number
  * base 10 floating numbers
  * comparison with epsilon

Does anyone know how these languages get the correct result?

              matz.

Shot (Piotr Szotkowski) wrote:

MenTaLguY:

The best you can do is test whether the result is
within some interval (epsilon) of the expected result:

( ( 14.95 * 0.6 ) - 8.97 ).abs < 1e-6

(Here, we've chosen 1e-6 as our epsilon, which is arbitrary but
probably "small enough" in this case. For mathematically intensive
code, you may need to be more careful.)

Any particular reason against using Float::EPSILON here? :slight_smile:

Maybe Float#== could simply be extended to consider the above? That
would most probably open another can of worms, though, and extending
Float#<=> would open yet another, I guess.

-- Shot

I think Float#== as it is is fine. Arguably it could use delta
comparison with Float::EPSILON and leave the exact comparison to eql?
But I'd like it if Float#in_delta(other, delta=Float::EPSILON) was in
core (personally I add it in my libs as Numeric#in_delta).

Regards
Stefan

···

--
Posted via http://www.ruby-forum.com/\.

Some numbers (like 0.1) cannot be represented exactly in binary with a
finite number of bits (because 0.1[base 10] =
0.0001100110011001100110011...[base 2]) and when they are represented
(as it happens with floating point representations), they lose
precision. So you must not test floating point for equality but always
rely on some tolerance and use an expression like MenTaLguY showed:

( 14.95 * 0.6 - 8.97 ).abs < tol

where tol depends on your application.

···

On 6/21/07, juan pedro meriño <juapdiaz@gmail.com> wrote:

You are rigth James, but you can better reponse why is a floating point
error?

Not all numbers can be represented by an arbitrarily small number of digits, and floating-point numbers only have so many digits available (for Ruby, 53 binary digits, which is about 16 decimal digits). In this case, the computation required more than 53 bits, so the result was approximate.

-mental

···

On Fri, 22 Jun 2007 04:40:29 +0900, "juan pedro meriño" <juapdiaz@gmail.com> wrote:

You are rigth James, but you can better reponse why is a floating point
error?

Yukihiro Matsumoto wrote:

Hi,

>I tried this in Delphi, smalltalk and oracle SQL and got the correct >result.

Interesting. There are a few ways to get the "correct" result.

  * fixed point number
  * base 10 floating numbers
  * comparison with epsilon

Does anyone know how these languages get the correct result?

              matz.

A simple way to get the correct figure is to do what is used often with currency to prevent these types of errors. If I enter 'puts 1495.0*6.0/1000.0' I get 8.97. The only thing necessary is to keep track of the number of decimal points.

···

In message "Re: Ruby doesn't know how to multiply" > on Fri, 22 Jun 2007 05:57:48 +0900, Lloyd Linklater <lloyd@2live4.com> writes:

Hi,

>I tried this in Delphi, smalltalk and oracle SQL and got the correct
>result.

Interesting. There are a few ways to get the "correct" result.

  * fixed point number
  * base 10 floating numbers
  * comparison with epsilon

Oracle uses base 100 floating numbers.
http://download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci03typ.htm#sthref431

···

On 6/22/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Does anyone know how these languages get the correct result?

matz,

I don't know which Smalltalk he used, but I just tried it in Squeak
and it evalutes to false, just like in Ruby.

···

On 6/21/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Hi,

In message "Re: Ruby doesn't know how to multiply" > on Fri, 22 Jun 2007 05:57:48 +0900, Lloyd Linklater <lloyd@2live4.com> writes:

>I tried this in Delphi, smalltalk and oracle SQL and got the correct
>result.

Interesting. There are a few ways to get the "correct" result.

  * fixed point number
  * base 10 floating numbers
  * comparison with epsilon

Does anyone know how these languages get the correct result?

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

I'd prefer in_delta?, but I think this is a great idea. Maybe you
should submit an RCR?

···

On 6/24/07, Stefan Rusterholz <apeiros@gmx.net> wrote:

I think Float#== as it is is fine. Arguably it could use delta
comparison with Float::EPSILON and leave the exact comparison to eql?
But I'd like it if Float#in_delta(other, delta=Float::EPSILON) was in
core (personally I add it in my libs as Numeric#in_delta).