From: Marnen Laibow-Koser on
Aldric Giacomoni wrote:
> Matthew K. Williams wrote:
>>> irb(main):016:0> 123.6 - 123.0
>>> => 0.599999999999994
>>>
>>> That's a little strange.. Isn't it?
>>
>> No, it's not. Welcome to the wonderfully confusing world of floating
>> point math...
>
> Oh, thanks. Can I have some pop-corn and an introductory pamphlet before
> I bash my head against the wall? :)

Most languages these days use IEEE 754-style floats, which leads to the
imprecision you saw.

http://c2.com/cgi/wiki?IeeeSevenFiftyFour

Don't use floats for serious arithmetic.

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen(a)marnen.org
--
Posted via http://www.ruby-forum.com/.

From: Robert Klemme on
On 28.10.2009 19:21, Matthew K. Williams wrote:
> On Thu, 29 Oct 2009, Aldric Giacomoni wrote:
>
>> Matthew K. Williams wrote:
>>>> irb(main):016:0> 123.6 - 123.0
>>>> => 0.599999999999994
>>>>
>>>> That's a little strange.. Isn't it?
>>> No, it's not. Welcome to the wonderfully confusing world of floating
>>> point math...
>> Oh, thanks. Can I have some pop-corn and an introductory pamphlet before
>> I bash my head against the wall? :)
>
> Pamphlet -> http://en.wikipedia.org/wiki/IEEE_754-2008
>
> Popcorn, well, it's kinda hard to transmit over the wire. ;-)

Easy to do with a modern email client - just needs support for POP3 and
a working firewall (for the heat). :-)

> As a rule of thumb, if you really care about the decimals, either use
> BigDecimal or integers (and keep track of where the decimal should be --
> this is common for $$$$). Unfortunately, this is not limited to ruby,
> either -- C, Java, and a host of other languages all are subject.

Absolutely: this is a common issue in *all* programming languages which
are not systems for symbolic math (like Mathematica) because they do not
work with real numbers but just rational numbers.

Cheers

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: Marnen Laibow-Koser on
Robert Klemme wrote:
> On 28.10.2009 19:21, Matthew K. Williams wrote:
>>> I bash my head against the wall? :)
>>
>> Pamphlet -> http://en.wikipedia.org/wiki/IEEE_754-2008
>>
>> Popcorn, well, it's kinda hard to transmit over the wire. ;-)
>
> Easy to do with a modern email client - just needs support for POP3 and
> a working firewall (for the heat). :-)

LOL!

>
>> As a rule of thumb, if you really care about the decimals, either use
>> BigDecimal or integers (and keep track of where the decimal should be --
>> this is common for $$$$). Unfortunately, this is not limited to ruby,
>> either -- C, Java, and a host of other languages all are subject.
>
> Absolutely: this is a common issue in *all* programming languages which
> are not systems for symbolic math (like Mathematica) because they do not
> work with real numbers but just rational numbers.

That is not the issue here -- after all, BigDecimal does precise
arithmetic, but only with rational numbers. The issue is rather that
IEEE 754 does an inadequate job of representing arbitrary rational
numbers, and the small errors are accumulated and magnified in
calculations.

>
> Cheers
>
> robert

Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen(a)marnen.org
--
Posted via http://www.ruby-forum.com/.

From: Gary Wright on

On Oct 28, 2009, at 3:30 PM, Marnen Laibow-Koser wrote:
> That is not the issue here -- after all, BigDecimal does precise
> arithmetic, but only with rational numbers. The issue is rather that
> IEEE 754 does an inadequate job of representing arbitrary rational
> numbers, and the small errors are accumulated and magnified in
> calculations.

I'd like to emphasize the fact that it is a very specific
representation problem that most often leads to a thread such
as this. That problem is a misunderstanding about the nature
of converting between a base 10 literal and a base 2 internal
value.

Many people don't realize that floating point literals written
in base 10 (such as 123.6) may not have an exact finite
representation when converted to base 2 and similarly a finite
base 2 floating point value may not have a finite representation
in base 10.

In the original post the floating point subtraction in the
expression (123.6 - 123.0) is handled just fine. The problem
is that 123.6 can't be represented exactly as a base 2 floating
point value so the subtraction that actually gets done is

123.599999999999994315658113919198513031005859375 - 123.0

and the result

0.599999999999994315658113919198513031005859375

is rounded via Ruby's Float#to_s method to

0.599999999999994

Gary Wright




From: Marnen Laibow-Koser on
Gary Wright wrote:
[...].
>
>
> Many people don't realize that floating point literals written
> in base 10 (such as 123.6) may not have an exact finite
> representation when converted to base 2

Right. 0.6 in binary has a repeating decimal -- 0.1001 repeating or
something like that.

> and similarly a finite
> base 2 floating point value may not have a finite representation
> in base 10.
[...]

I think not. Every number of the form 1/(2^n) has a terminating decimal
in base 10. Am I wrong?

The problems, of course, arise with numbers like 1/3, which doesn't
terminate in either base. This is what the Rational class is good for.

>
Best,
--
Marnen Laibow-Koser
http://www.marnen.org
marnen(a)marnen.org
--
Posted via http://www.ruby-forum.com/.