Forum: Ruby float equality

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ab9859d0cd0c321ab44411a0a35902f2?d=identicon&s=25 guille lists (Guest)
on 2008-10-27 17:51
(Received via mailing list)
Hi,

sorry if this is a very naive question (I'm new to ruby), but I
haven't found an explication yet. When comparing to floats in ruby I
came across this:

>> a = 0.1
=> 0.1
>> b = 1 - 0.9
=> 0.1
>> a == b
=> false
>> a > b
=> true
>> a < b
=> false
>> a <=> b
=> 1

I'm a bit lost here, shouldn't (0.1) and (1 - 0.9) be equals regarding
the == operator? I also found that for example 0.3 == (0.2 + 0.1)
returns false, etc.

guille

PD: I'm using ruby 1.8.6 (2008-03-03 patchlevel 114)
[universal-darwin9.0]
289cf19aa581c445915c072bf45c5e25?d=identicon&s=25 Todd Benson (Guest)
on 2008-10-27 18:10
(Received via mailing list)
On Mon, Oct 27, 2008 at 11:50 AM, guille lists <guilledist@gmail.com>
wrote:
>>> a == b
> returns false, etc.
Most people will  point you to this:
http://en.wikipedia.org/wiki/Floating_point_arithmetic

There are several ways around it (using BigDecimal, Rational, Integers,
etc.)

Totally off-topic, but has any one figured out exactly why 1/9
(0.111...) plus 8/9 (0.888...) is 1 instead of 0.999... :-)

Todd
Beb77c4602c3cac7a12149431366ed11?d=identicon&s=25 The Higgs bozo (higgsbozo)
on 2008-10-27 18:10
guille lists wrote:
> I'm a bit lost here, shouldn't (0.1) and (1 - 0.9) be equals regarding
> the == operator?

Nope.  Floating-point is always inexact.  This is a computer thing, not
a Ruby thing.  The issue applies to all languages everywhere which use
floating point.

Here you can see the two values are slightly different:

irb(main):001:0> 1 - 0.9 == 0.1
=> false
irb(main):002:0> [1 - 0.9].pack("D")
=> "\230\231\231\231\231\231\271?"
irb(main):003:0> [0.1].pack("D")
=> "\232\231\231\231\231\231\271?"
7a561ec0875fcbbe3066ea8fe288ec77?d=identicon&s=25 Sebastian Hungerecker (Guest)
on 2008-10-27 18:16
(Received via mailing list)
guille lists wrote:
> I'm a bit lost here, shouldn't (0.1) and (1 - 0.9) be equals regarding
> the == operator?

No. The result of 1 - 0.9 using floating point math is not actually 0.1.
In
irb it is displayed as 0.1, but that's only because Float#inspect
rounds.
Using printf you can see that the result of 1-0.9 actually is
0.09999lots:
>> printf "%.30f", 1-0.9
0.099999999999999977795539507497
0.1 itself isn't actually 0.1 either - it's
0.100000000000000005551115123126...
Because of this you should not check two floats for equality (usually
you want
to check for a delta or not use floats at all). This is so because of
the
inherent inaccuracy of floating point maths. See this for more
information:
http://docs.sun.com/source/806-3568/ncg_goldberg.html

HTH,
Sebastian
A61ecce13ed142622f24a5ca3a123922?d=identicon&s=25 Matthew Moss (Guest)
on 2008-10-27 18:52
(Received via mailing list)
> Totally off-topic, but has any one figured out exactly why 1/9
> (0.111...) plus 8/9 (0.888...) is 1 instead of 0.999... :-)

Ummm... because 1/9 + 8/9 == (1 + 8)/9 == 9/9 == 1 ?

And...  because 0.999... == 1?

    x = 0.999...
  10x = 9.999...
  (10x - x) = 9.999... - 0.999...
   9x = 9
    x = 1
Ab9859d0cd0c321ab44411a0a35902f2?d=identicon&s=25 guille lists (Guest)
on 2008-10-27 20:32
(Received via mailing list)
Thanks a lot for the answers and references, and sorry for not having
check deeper on google
(http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/...).

So I guess that if one wants to work for example with float numbers in
the range [0,1], the best way to do it is by normalising from an
integer interval depending on the precision you want, say [0,100] for
two decimal digits precision, and so on. Is there any other better
approach? Does the use of BigDecimal impose a severe penalty on
performance?


guille
Beb77c4602c3cac7a12149431366ed11?d=identicon&s=25 The Higgs bozo (higgsbozo)
on 2008-10-27 20:48
Matthew Moss wrote:
>> Totally off-topic, but has any one figured out exactly why 1/9
>> (0.111...) plus 8/9 (0.888...) is 1 instead of 0.999... :-)
>
> Ummm... because 1/9 + 8/9 == (1 + 8)/9 == 9/9 == 1 ?
>
> And...  because 0.999... == 1?
>
>     x = 0.999...
>   10x = 9.999...
>   (10x - x) = 9.999... - 0.999...
>    9x = 9
>     x = 1

While your answer is correct, you cannot subtract infinities as shown
in your proof.  Look at this:

      x == 1 - 1 + 1 - 1 + 1 - 1 + 1 - ...
      x ==     1 - 1 + 1 - 1 + 1 - 1 + ...
  ----------------------------------------
     2x == 1 + 0 + 0 + 0 + 0 + 0 + 0 + ...
      x == 0.5

Does x == 0.5?  No, because x was never a number in the first place
because the given series does not converge.  Your proof appears to
work because you've already assumed 0.99999... converges, but that is
what you are trying to prove.

P.S.  Euler thought the answer was x == 0.5.
4d5b5dd4e263d780a5dfe7ac8b8ac98c?d=identicon&s=25 Tim Pease (Guest)
on 2008-10-27 21:12
(Received via mailing list)
On Mon, Oct 27, 2008 at 11:09 AM, Todd Benson <caduceass@gmail.com>
wrote:
>
> Totally off-topic, but has any one figured out exactly why 1/9
> (0.111...) plus 8/9 (0.888...) is 1 instead of 0.999... :-)
>

I figured it out once, but I can't remember precisely how it worked.

TwP
D0338c0de4cb3c5c17300396159933d1?d=identicon&s=25 Axel Etzold (Guest)
on 2008-10-27 21:14
(Received via mailing list)
-------- Original-Nachricht --------
> Datum: Tue, 28 Oct 2008 04:31:06 +0900
> Von: "guille lists" <guilledist@gmail.com>
> An: ruby-talk@ruby-lang.org
> Betreff: Re: float equality

>
>
> guille

Dear guille,

you could use some approximate equality check:

class Float
   def approx_equal?(other,threshold)
       if (self-other).abs<threshold    # "<" not exact either ;-)
          return true
       else
          return false
       end
   end
end

a=0.1
b=1.0-0.9
threshold=10**(-5)

p a.approx_equal?(b,threshold)


Best regards,

Axel
58d1114fe29aab2d433231a722dd2034?d=identicon&s=25 Bilyk, Alex (Guest)
on 2008-10-27 21:31
(Received via mailing list)
Mathematically 1.(0) is the same thing as 0.(9). Computers simply
represent this to whatever precision they can.
4d5b5dd4e263d780a5dfe7ac8b8ac98c?d=identicon&s=25 Tim Pease (Guest)
on 2008-10-27 21:41
(Received via mailing list)
On Oct 27, 2008, at 2:29 PM, Bilyk, Alex wrote:

> Mathematically 1.(0) is the same thing as 0.(9). Computers simply
> represent this to whatever precision they can.
>

Hmmm ... my humor is a little to obtuse today. I was hoping the word
"precisely" would cause a mental link to the word "precision" which is
what this problem is all about -- precision and computer
representations of floating point values.

Alas. I'll stick with my day job of writing software.

Blessings,
TwP
A61ecce13ed142622f24a5ca3a123922?d=identicon&s=25 Matthew Moss (Guest)
on 2008-10-27 21:58
(Received via mailing list)
On Oct 27, 2008, at 2:48 PM, The Higgs bozo wrote:

>>  (10x - x) = 9.999... - 0.999...
>      x == 0.5
>
> Does x == 0.5?  No, because x was never a number in the first place
> because the given series does not converge.  Your proof appears to
> work because you've already assumed 0.99999... converges, but that is
> what you are trying to prove.


But 0.999... does converge, while 1 - 1 + 1 - 1 +... does not.
A61ecce13ed142622f24a5ca3a123922?d=identicon&s=25 Matthew Moss (Guest)
on 2008-10-27 22:02
(Received via mailing list)
>>     x ==     1 - 1 + 1 - 1 + 1 - 1 + ...
> But 0.999... does converge, while 1 - 1 + 1 - 1 +... does not.
On re-reading, I see that you weren't so much questioning whether
0.999... converges, but that my proof uses circular reasoning. Yeah, I
suppose that's correct.

Still, 0.999... does converge and is 1. Nyah!  :p   I just don't
remember the better proof I once knew.
4fea1ef11180adaaa299d503ca6010d0?d=identicon&s=25 John W Kennedy (Guest)
on 2008-10-28 03:50
(Received via mailing list)
The Higgs bozo wrote:
> guille lists wrote:
>> I'm a bit lost here, shouldn't (0.1) and (1 - 0.9) be equals regarding
>> the == operator?
>
> Nope.  Floating-point is always inexact.

What you mean is that binary floating point inexactly represents decimal
fractions.

> This is a computer thing, not
> a Ruby thing.  The issue applies to all languages everywhere which use
> floating point.

...binary floating point.
This topic is locked and can not be replied to.