Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #13650 > unrolled thread

comparing floating point numbers

Started byAdam Majewski <adammaj1@o2.pl>
First post2012-01-29 19:48 +0100
Last post2012-01-30 06:26 -0800
Articles 17 — 14 participants

Back to article view | Back to comp.lang.c++


Contents

  comparing floating point numbers Adam Majewski <adammaj1@o2.pl> - 2012-01-29 19:48 +0100
    Re: comparing floating point numbers BCFD36 <bcfd36@cruzio.com> - 2012-01-29 11:02 -0800
      Re: comparing floating point numbers "MikeWhy" <boat042-nospam@yahoo.com> - 2012-01-29 13:25 -0600
        Re: comparing floating point numbers "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2012-01-29 20:40 +0100
      Re: comparing floating point numbers Adam Majewski <adammaj1@o2.pl> - 2012-01-30 18:03 +0100
    Re: comparing floating point numbers Marcel Müller <news.5.maazl@spamgourmet.com> - 2012-01-29 21:34 +0100
      Re: comparing floating point numbers BCFD36 <bcfd36@cruzio.com> - 2012-01-29 14:55 -0800
        Re: comparing floating point numbers Miles Bader <miles@gnu.org> - 2012-01-30 11:48 +0900
          Re: comparing floating point numbers Juha Nieminen <nospam@thanks.invalid> - 2012-01-30 14:53 +0000
      Re: comparing floating point numbers scott@slp53.sl.home (Scott Lurndal) - 2012-01-30 17:22 +0000
        Re: comparing floating point numbers Robert Wessel <robertwessel2@yahoo.com> - 2012-01-30 13:55 -0600
        Re: comparing floating point numbers glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-02-13 01:56 +0000
    Re: comparing floating point numbers LR <lruss@superlink.net> - 2012-01-29 18:30 -0500
      Re: comparing floating point numbers Thomas Boell <tboell@domain.invalid> - 2012-01-30 16:29 +0100
    Re: comparing floating point numbers Christian Gollwitzer <auriocus@gmx.de> - 2012-01-30 08:07 +0100
      Re: comparing floating point numbers glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-02-13 01:59 +0000
    Re: comparing floating point numbers Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-30 06:26 -0800

#13650 — comparing floating point numbers

FromAdam Majewski <adammaj1@o2.pl>
Date2012-01-29 19:48 +0100
Subjectcomparing floating point numbers
Message-ID<jg44ad$fti$1@news.icm.edu.pl>
Hi,

I have seen code that compers like that :

if (b == 0.0  && (a == 0.25 || a == -0.75))

so I have checked it :

#include <iostream>

using namespace std;

int main() {
    cout  << boolalpha
          << "The true expression  0.25 == 0.25000000000000001 yields : "
          << (0.25 ==                      0.25000000000000001) << endl
          << "The false expression 0.25 == 0.2500000000000001 yields: "
          << (0.25 ==                      0.2500000000000001) << endl;
}


Is it operator overloadin ? Is it good code ?

TIA

Adam

[toc] | [next] | [standalone]


#13651

FromBCFD36 <bcfd36@cruzio.com>
Date2012-01-29 11:02 -0800
Message-ID<jg4540$n0$1@speranza.aioe.org>
In reply to#13650
On 1/29/12 10:48 AM, Adam Majewski wrote:
> Hi,
>
> I have seen code that compers like that :
>
> if (b == 0.0 && (a == 0.25 || a == -0.75))
>
> so I have checked it :
>
> #include <iostream>
>
> using namespace std;
>
> int main() {
> cout << boolalpha
> << "The true expression 0.25 == 0.25000000000000001 yields : "
> << (0.25 == 0.25000000000000001) << endl
> << "The false expression 0.25 == 0.2500000000000001 yields: "
> << (0.25 == 0.2500000000000001) << endl;
> }
>
>
> Is it operator overloadin ? Is it good code ?
>
> TIA
>
> Adam


So what was the output from the code? I would think you might get 
different answers with different compilers.

-- 
Dave Scruggs

[toc] | [prev] | [next] | [standalone]


#13652

From"MikeWhy" <boat042-nospam@yahoo.com>
Date2012-01-29 13:25 -0600
Message-ID<jg46f1$852$1@dont-email.me>
In reply to#13651
"BCFD36" <bcfd36@cruzio.com> wrote in message 
news:jg4540$n0$1@speranza.aioe.org...
> On 1/29/12 10:48 AM, Adam Majewski wrote:
>> Hi,
>>
>> I have seen code that compers like that :
>>
>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>>
>> so I have checked it :
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> int main() {
>> cout << boolalpha
>> << "The true expression 0.25 == 0.25000000000000001 yields : "
>> << (0.25 == 0.25000000000000001) << endl
>> << "The false expression 0.25 == 0.2500000000000001 yields: "
>> << (0.25 == 0.2500000000000001) << endl;
>> }
>>
>>
>> Is it operator overloadin ? Is it good code ?
>>
>> TIA
>>
>> Adam
>
>
> So what was the output from the code? I would think you might get 
> different answers with different compilers.

The representation of a double precision floating point is standardized. It 
has 53 bits of mantissa, roughly 16 decimal digits of precision.

[toc] | [prev] | [next] | [standalone]


#13653

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2012-01-29 20:40 +0100
Message-ID<jg47b2$de8$1@dont-email.me>
In reply to#13652
On 29.01.2012 20:25, MikeWhy wrote:
>
> "BCFD36" <bcfd36@cruzio.com> wrote in message
> news:jg4540$n0$1@speranza.aioe.org...
>> On 1/29/12 10:48 AM, Adam Majewski wrote:
>>> Hi,
>>>
>>> I have seen code that compers like that :
>>>
>>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>>>
>>> so I have checked it :
>>>
>>> #include <iostream>
>>>
>>> using namespace std;
>>>
>>> int main() {
>>> cout << boolalpha
>>> << "The true expression 0.25 == 0.25000000000000001 yields : "
>>> << (0.25 == 0.25000000000000001) << endl
>>> << "The false expression 0.25 == 0.2500000000000001 yields: "
>>> << (0.25 == 0.2500000000000001) << endl;
>>> }
>>>
>>>
>>> Is it operator overloadin ? Is it good code ?
>>>
>>> TIA
>>>
>>> Adam
>>
>>
>> So what was the output from the code? I would think you might get
>> different answers with different compilers.
>
> The representation of a double precision floating point is standardized.
> It has 53 bits of mantissa, roughly 16 decimal digits of precision.

Sorry, no. While there are standards for floating point representation, 
and in particular the one you're referring (namely IEEE 754), how 
floating point values are represented with a given C++ compiler depends 
formally on the compiler, and in practice on the API for the OS that the 
compiler targets. std::numeric_limits<double>::iec something something 
tells you whether IEEE *representation* is used. It was meant to also 
tell you whether the compiler adheres to that standard. Unfortunately, 
in practice it only tells you about the representation.

Cheers & hth.,

- Alf

[toc] | [prev] | [next] | [standalone]


#13664

FromAdam Majewski <adammaj1@o2.pl>
Date2012-01-30 18:03 +0100
Message-ID<jg6ih0$kid$1@news.icm.edu.pl>
In reply to#13651
On 29.01.2012 20:02, BCFD36 wrote:
> On 1/29/12 10:48 AM, Adam Majewski wrote:
>> Hi,
>>
>> I have seen code that compers like that :
>>
>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>>
>> so I have checked it :
>>
>> #include <iostream>
>>
>> using namespace std;
>>
>> int main() {
>> cout << boolalpha
>> << "The true expression 0.25 == 0.25000000000000001 yields : "
>> << (0.25 == 0.25000000000000001) << endl
>> << "The false expression 0.25 == 0.2500000000000001 yields: "
>> << (0.25 == 0.2500000000000001) << endl;
>> }
>>
>>
>> Is it operator overloadin ? Is it good code ?
>>
>> TIA
>>
>> Adam
>
>
> So what was the output from the code?

a@acer:~/cpp/comparison$ g++ c.cpp
a@acer:~/cpp/comparison$ ./a.out
The true expression  0.25 == 0.25000000000000001 yields : true
The false expression 0.25 == 0.2500000000000001 yields: false





Adam

[toc] | [prev] | [next] | [standalone]


#13654

FromMarcel Müller <news.5.maazl@spamgourmet.com>
Date2012-01-29 21:34 +0100
Message-ID<4f25ad65$0$6577$9b4e6d93@newsspool3.arcor-online.net>
In reply to#13650
On 29.01.2012 19:48, Adam Majewski wrote:
> I have seen code that compers like that :
>
> if (b == 0.0 && (a == 0.25 || a == -0.75))

Comparing floating point numbers for equality is almost always a bug. 
Only singular values like 0.0 are usually safe.


Marcel

[toc] | [prev] | [next] | [standalone]


#13655

FromBCFD36 <bcfd36@cruzio.com>
Date2012-01-29 14:55 -0800
Message-ID<jg4io7$5o2$1@speranza.aioe.org>
In reply to#13654
On 1/29/12 12:34 PM, Marcel Müller wrote:
> On 29.01.2012 19:48, Adam Majewski wrote:
>> I have seen code that compers like that :
>>
>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>
> Comparing floating point numbers for equality is almost always a bug.
> Only singular values like 0.0 are usually safe.
>
>
> Marcel

Agreed. And anyone who made it past the 1st Intro to CS class would know 
that. I've no idea of the Original Poster's background so I wasn't going 
to speculate on his training. I'm pretty sure english is a 2nd language 
for him so what he asked and what he meant to ask were not quite the 
same. I can't fault someone for that.

But, yes, comparing floats for equality is not a good thing.

-- 
Dave Scruggs

[toc] | [prev] | [next] | [standalone]


#13658

FromMiles Bader <miles@gnu.org>
Date2012-01-30 11:48 +0900
Message-ID<87sjixrjlc.fsf@catnip.gol.com>
In reply to#13655
BCFD36 <bcfd36@cruzio.com> writes:
>>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>>
>> Comparing floating point numbers for equality is almost always a bug.
>> Only singular values like 0.0 are usually safe.
>
> Agreed. And anyone who made it past the 1st Intro to CS class would
> know that. I've no idea of the Original Poster's background so I
> wasn't going to speculate on his training. I'm pretty sure english is
> a 2nd language for him so what he asked and what he meant to ask were
> not quite the same. I can't fault someone for that.
>
> But, yes, comparing floats for equality is not a good thing.

... unless checking for the aforementioned "singular values", resulting
from simple assignment rather than calculation, and known to have a
representation that cannot suffer from precision loss etc.

The latter _is_ perfectly fine, which is why, for instance, a simplistic
compiler warning to complain about floating-point equality comparison
isn't so useful...

-miles

-- 
Brain, n. An apparatus with which we think we think.

[toc] | [prev] | [next] | [standalone]


#13662

FromJuha Nieminen <nospam@thanks.invalid>
Date2012-01-30 14:53 +0000
Message-ID<4f26aed3$0$2766$7b1e8fa0@news.nbl.fi>
In reply to#13658
Miles Bader <miles@gnu.org> wrote:
> The latter _is_ perfectly fine, which is why, for instance, a simplistic
> compiler warning to complain about floating-point equality comparison
> isn't so useful...

  There are situations where you actually might want to make a ==
comparison instead of anything else. One such example that I have
personal experience about is when implementing a class that is a
wrapper around a multiple-precision floating point library. In this
particular case, I had an optimization that if the object is
initialized with the exact value of 0.0 or 1.0 (in their double
versions of the constructors/assignment), then it will use cached
data instead of allocating new data. In this case comparing with ==
is quite crucial, because if the given value differs from those even
by the tiniest amount, using the cached data would be wrong. However,
it's quite usual to initialize such values with 0.0 or 1.0.

  If, however, you want to make a ranged comparison to account for
rounding errors, the vast majority of even experienced programmers
don't realize how difficult that task actually is. Whatever your
solution, it will not work properly in all possible cases. (The most
naive solution of "fabs(a-b) < epsilon" is problematic because the
precision of the comparison depends on the magnitude of the values:
Larger values will be compared with a significantly stricter precision,
ie. less rounding error is allowed, than values closer to zero.)

  I have written an article about this problem:

http://warp.povusers.org/programming/floating_point_caveats.html

[toc] | [prev] | [next] | [standalone]


#13666

Fromscott@slp53.sl.home (Scott Lurndal)
Date2012-01-30 17:22 +0000
Message-ID<4lAVq.191683$IC2.35146@news.usenetserver.com>
In reply to#13654
=?ISO-8859-1?Q?Marcel_M=FCller?= <news.5.maazl@spamgourmet.com> writes:
>On 29.01.2012 19:48, Adam Majewski wrote:
>> I have seen code that compers like that :
>>
>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>
>Comparing floating point numbers for equality is almost always a bug.

Assuming a binary floating point representation, then yes.

For decimal representations (BCD fixed and floating point) as implemented by some
mainframes and the new decimal support in C, there should be no problems
with equality.

scott

[toc] | [prev] | [next] | [standalone]


#13668

FromRobert Wessel <robertwessel2@yahoo.com>
Date2012-01-30 13:55 -0600
Message-ID<22tdi7lhhbc3mv7mlh1m9ois45384cbs57@4ax.com>
In reply to#13666
On 30 Jan 2012 17:22:08 GMT, scott@slp53.sl.home (Scott Lurndal)
wrote:

>=?ISO-8859-1?Q?Marcel_M=FCller?= <news.5.maazl@spamgourmet.com> writes:
>>On 29.01.2012 19:48, Adam Majewski wrote:
>>> I have seen code that compers like that :
>>>
>>> if (b == 0.0 && (a == 0.25 || a == -0.75))
>>
>>Comparing floating point numbers for equality is almost always a bug.
>
>Assuming a binary floating point representation, then yes.
>
>For decimal representations (BCD fixed and floating point) as implemented by some
>mainframes and the new decimal support in C, there should be no problems
>with equality.


No it doesn't.  While a decimal FP representation can (obviously)
exactly represent more decimal values in its range, it doesn't help
the accumulated round off error problem one bit, unless all the
operands are (now) directly representable as exact values (and some
other conditions are met - mainly that you computation ever results in
a value that cannot be represented exactly - so you have great
restrictions on the use of division, for example).

For example, you had better not assume that ((2/3)*6) == ((2*6)/3),
with either decimal or binary FP.

[toc] | [prev] | [next] | [standalone]


#13955

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-02-13 01:56 +0000
Message-ID<jh9qjp$186$1@speranza.aioe.org>
In reply to#13666
Scott Lurndal <scott@slp53.sl.home> wrote:

(someone asked about)

>>> if (b == 0.0 && (a == 0.25 || a == -0.75))

>>Comparing floating point numbers for equality is almost always a bug.

> Assuming a binary floating point representation, then yes.

> For decimal representations (BCD fixed and floating point) as 
> implemented by some mainframes and the new decimal support in C, 
> there should be no problems with equality.

But 0.25 and -0.75 are nice binary fractions. (0.01 and -0.11)

Even so, I would not suggest actually doing it, but I would
consider it a bug for a compiler to get wrong.

Now, ask about decimal fractions that aren't terminating
binary fractions, and that is a different question.

-- glen

[toc] | [prev] | [next] | [standalone]


#13656

FromLR <lruss@superlink.net>
Date2012-01-29 18:30 -0500
Message-ID<4f25d682$0$15922$cc2e38e6@news.uslec.net>
In reply to#13650
Adam Majewski wrote:

> I have seen code that compers like that :
> 
> if (b == 0.0  && (a == 0.25 || a == -0.75))


I suggest these two articles in the FAQ
http://www.parashift.com/c++-faq-lite/index.html

[29.16] Why is floating point so inaccurate? Why doesn't this print 0.43?
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.16

Perhaps more relevant to your question and with some interesting references.
[29.17] Why doesn't my floating-point comparison work?
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17

[toc] | [prev] | [next] | [standalone]


#13663

FromThomas Boell <tboell@domain.invalid>
Date2012-01-30 16:29 +0100
Message-ID<20120130162912.0b18f547@arcadia>
In reply to#13656
On Sun, 29 Jan 2012 18:30:06 -0500
LR <lruss@superlink.net> wrote:

> Adam Majewski wrote:
> 
> > I have seen code that compers like that :
> > 
> > if (b == 0.0  && (a == 0.25 || a == -0.75))
> 
> 
> I suggest these two articles in the FAQ
> http://www.parashift.com/c++-faq-lite/index.html
> 
> [29.16] Why is floating point so inaccurate? Why doesn't this print 0.43?
> http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.16
> 
> Perhaps more relevant to your question and with some interesting references.
> [29.17] Why doesn't my floating-point comparison work?
> http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17

Another very informative article about this topic is this one:

Comparing floating point numbers - Bruce Dawson
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

[toc] | [prev] | [next] | [standalone]


#13659

FromChristian Gollwitzer <auriocus@gmx.de>
Date2012-01-30 08:07 +0100
Message-ID<jg5fkd$lo1$1@dont-email.me>
In reply to#13650
Am 29.01.12 19:48, schrieb Adam Majewski:
> Hi,
>
> I have seen code that compers like that :
>
> if (b == 0.0 && (a == 0.25 || a == -0.75))
>

In this special case it /might/ work, because all values are prefectly 
representably in binary, i.e. 0.25d=0.01b and 0.75d=0.11b. If a is 
computed like:

double a = 3;
a /= 4;

then a==0.75 is true on most current systems. However, in most other 
cases it is not recommended to compare floating point values for equality.

	Christian

[toc] | [prev] | [next] | [standalone]


#13956

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-02-13 01:59 +0000
Message-ID<jh9qpp$186$2@speranza.aioe.org>
In reply to#13659
Christian Gollwitzer <auriocus@gmx.de> wrote:

(snip)
> In this special case it /might/ work, because all values are prefectly 
> representably in binary, i.e. 0.25d=0.01b and 0.75d=0.11b. If a is 
> computed like:

> double a = 3;
> a /= 4;

> then a==0.75 is true on most current systems. However, in most other 
> cases it is not recommended to compare floating point values for equality.

I believe that C (and C++) require integers to have a binary
representation, but not floating point values. That a base 13
floating point would be standard conforming, and fail in cases
like this. 

(Fortran allows for any integer base greater than one for both
floating point and integer representations.)

But on a binary, or other power of two base, system it should work.

-- glen

[toc] | [prev] | [next] | [standalone]


#13661

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-01-30 06:26 -0800
Message-ID<3aad1c01-383b-4590-9cfb-2f0856e9b52d@dp8g2000vbb.googlegroups.com>
In reply to#13650
On Jan 29, 6:48 pm, Adam Majewski <adamm...@o2.pl> wrote:

> I have seen code that compers like that :
>
> if (b == 0.0  && (a == 0.25 || a == -0.75))

in general not very good. Though other posters have pointed out that
these are rather special values.

> so I have checked it :
>
> #include <iostream>
>
> using namespace std;
>
> int main() {
>     cout  << boolalpha

where is boolalpha declared? Is it part of iostream?

>           << "The true expression  0.25 == 0.25000000000000001 yields : "
>           << (0.25 ==                      0.25000000000000001) << endl
>           << "The false expression 0.25 == 0.2500000000000001 yields: "
>           << (0.25 ==                      0.2500000000000001) << endl;

what do you expect this to give as a result?

> }
>
> Is it operator overloadin ?

no. Why would it be?

> Is it good code ?

no. don't think so but then I'm not sure what you're trying to show

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web