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, removed_email[email protected] [email protected]:

On Fri, Jun 22, 2007 at 04:25:04AM +0900, [email protected] wrote:

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”

http://en.wikipedia.org/wiki/Rounding_error

Thanks,

Roberto Prado.

–Greg

On 6/21/07, [email protected] [email protected] wrote:

ruby 1.8.5. I’ll give it a try on 1.8.6 and let you know.

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 Jun 21, 2007, at 2:30 PM, juan pedro meriño wrote:

I thingh that it is a bug

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

http://en.wikipedia.org/wiki/Floating_point

James Edward G. II

On Fri, 22 Jun 2007 04:25:04 +0900, “[email protected]”

[email protected] 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

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

error?

On 6/21/07, juan pedro meriño [email protected] wrote:

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

error?

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.

thank you!

2007/6/21, MenTaLguY [email protected]:

On Fri, 22 Jun 2007 04:40:29 +0900, “juan pedro meriÃ±o”

[email protected] 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

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

assert_in_delta()

On Jun 21, 3:49 pm, “Adriano F.” [email protected] wrote:

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.

I’m starting to remember something about that on my computer

architecture course. But it’s something so technical and I’m so used

to high level programming, that I couldn’t remember…

On Jun 21, 3:21 pm, “[email protected]” [email protected] wrote:

ruby 1.8.5. I’ll give it a try on 1.8.6 and let you know.

Thanks,

Roberto Prado.

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 Fri, 22 Jun 2007 05:00:03 +0900, “[email protected]”

[email protected] wrote:

I’m starting to remember something about that on my computer

architecture course. But it’s something so technical and I’m so used

to high level programming, that I couldn’t remember…

I guess it goes to show that one never really escapes this stuff,

even in “high level” programming.

-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.

Yukihiro M. wrote:

- 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.

On 6/21/07, Michael W. Ryder [email protected] wrote:

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.

Much better is to store the numbers as integers and convert to

decimal, guaranteeing zero loss.

Hi,

In message “Re: Ruby doesn’t know how to multiply”

on Fri, 22 Jun 2007 05:57:48 +0900, Lloyd L.

[email protected] 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.`

Rob B. wrote:

Which are just different ways of saying “fixed point numbers” that matz

had at the top of his list. Believe me when I tell you that dealing

with fixed point can be challenging. I worked on part of an air traffic

control system about 20 years ago that used 16-bit values where the LSB

for a distance value represented 1/256nm (nautical mile). There was no

floating-point co-processor in the M68000-based systems and the C code

was compiled with a special, non-standard compiler that would do things

like (16-bits * 16-bits)/16-bits was assumed to produce a 16-bit result

unless you had a typecast to indicate otherwise.

I think we have a difference of understanding of what fixed point means.

I look at fixed point numbers meaning something like 1057 means 10.57

in the real world. I was thinking more of something that shifted the

floating point number to remove the fractions and later replaced the

decimal point in the correct position, which I do not consider to be

fixed point math.

My simple calculator is more precise for some math operations than my

expensive PC. Maybe we need to implement something like General Decimal

Arithmetic which is available for C++ and Java at

http://www2.hursley.ibm.com/decimal/ in Ruby. It may be as simple as

writing wrappers for the operations, I haven’t had to time to look

closer at the package.

On Jun 21, 2007, at 8:48 PM, Gregory B. wrote:

On 6/21/07, Michael W. Ryder [email protected] wrote:

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.

Much better is to store the numbers as integers and convert to

decimal, guaranteeing zero loss.

Which are just different ways of saying “fixed point numbers” that

matz had at the top of his list. Believe me when I tell you that

dealing with fixed point can be challenging. I worked on part of an

air traffic control system about 20 years ago that used 16-bit values

where the LSB for a distance value represented 1/256nm (nautical

mile). There was no floating-point co-processor in the M68000-based

systems and the C code was compiled with a special, non-standard

compiler that would do things like (16-bits * 16-bits)/16-bits was

assumed to produce a 16-bit result unless you had a typecast to

indicate otherwise.

The other way to get truth from 14.95*0.6 == 8.97 is to use less

precise representations than you get with a typical Float. Of

course, that’s going to be a problem as the numbers get bigger

-Rob

Rob B. http://agileconsultingllc.com

[email protected]