Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #13650 > unrolled thread
| Started by | Adam Majewski <adammaj1@o2.pl> |
|---|---|
| First post | 2012-01-29 19:48 +0100 |
| Last post | 2012-01-30 06:26 -0800 |
| Articles | 17 — 14 participants |
Back to article view | Back to comp.lang.c++
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
| From | Adam Majewski <adammaj1@o2.pl> |
|---|---|
| Date | 2012-01-29 19:48 +0100 |
| Subject | comparing 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]
| From | BCFD36 <bcfd36@cruzio.com> |
|---|---|
| Date | 2012-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]
| From | "MikeWhy" <boat042-nospam@yahoo.com> |
|---|---|
| Date | 2012-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]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Adam Majewski <adammaj1@o2.pl> |
|---|---|
| Date | 2012-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]
| From | Marcel Müller <news.5.maazl@spamgourmet.com> |
|---|---|
| Date | 2012-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]
| From | BCFD36 <bcfd36@cruzio.com> |
|---|---|
| Date | 2012-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]
| From | Miles Bader <miles@gnu.org> |
|---|---|
| Date | 2012-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2012-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]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2012-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]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2012-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]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-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]
| From | LR <lruss@superlink.net> |
|---|---|
| Date | 2012-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]
| From | Thomas Boell <tboell@domain.invalid> |
|---|---|
| Date | 2012-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]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2012-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]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-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]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-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