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]
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
···
On Mon, Oct 27, 2008 at 11:50 AM, guille lists <guilledist@gmail.com> wrote:
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.
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:
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
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.
···
--
John W. Kennedy
"I want everybody to be smart. As smart as they can be. A world of ignorant people is too dangerous to live in."
-- Garson Kanin. "Born Yesterday"
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?
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.
Mathematically 1.(0) is the same thing as 0.(9). Computers simply represent this to whatever precision they can.
···
-----Original Message-----
From: Tim Pease [mailto:tim.pease@gmail.com]
Sent: Monday, October 27, 2008 1:11 PM
To: ruby-talk ML
Subject: Re: float equality
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.
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
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
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
···
On Oct 27, 2008, at 2:29 PM, Bilyk, Alex wrote:
-----Original Message-----
From: Tim Pease [mailto:tim.pease@gmail.com]
Sent: Monday, October 27, 2008 1:11 PM
To: ruby-talk ML
Subject: Re: float equality
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.
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.
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.
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! I just don't remember the better proof I once knew.