Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Regarding Q. 14-5 (http://www.velocityreviews.com/forums/t440393-regarding-q-14-5-a.html)

 Brian Dude 12-03-2005 05:10 AM

Regarding Q. 14-5

Hello, I understand the part about not comparing two floating-point
numbers for exact-ness. Does this also apply to comparisons to constants?
i.e.:

double f;

if ( f <= 1.0){
...
}

TIA,
Brian

 pete 12-03-2005 06:32 AM

Re: Regarding Q. 14-5

Brian Dude wrote:
>
> Hello, I understand the part
> about not comparing two floating-point
> numbers for exact-ness.

There's nothing wrong with comparing two doubles
with a relational operator.

> Does this also apply to comparisons to constants?
> i.e.:
>
> double f;
>
> if ( f <= 1.0){
> ...
> }

--
pete

 Flash Gordon 12-03-2005 09:43 AM

Re: Regarding Q. 14-5

pete wrote:
> Brian Dude wrote:
>> Hello, I understand the part
>> about not comparing two floating-point
>> numbers for exact-ness.

>
> Your example doesn't show it.
> There's nothing wrong with comparing two doubles
> with a relational operator.
>
>> Does this also apply to comparisons to constants?
>> i.e.:
>>
>> double f;
>>
>> if ( f <= 1.0){
>> ...
>> }

However, something like
if (f == CONSTANT)

1) If f is calculated (and why else would it be a variable) it might not
be exactly CONSTANT even if an infinite precision system said it was.
2) For some values CONSTANT won't be exactly what you think.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

 Mark McIntyre 12-03-2005 12:00 PM

Re: Regarding Q. 14-5

On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
<pfiland@mindspring.com> wrote:

>Brian Dude wrote:
>>
>> Hello, I understand the part
>> about not comparing two floating-point
>> numbers for exact-ness.

>
>There's nothing wrong with comparing two doubles
>with a relational operator.

Except that even when equal as far as expectation is concerned, they
might compare unequal.

#include <stdio.h>
#include <math.h>

int main(void)
{
double x = acos(0);

x=cos(((x*123.4567)-100)/123.4567 +100/123.4567);

printf("%s\n", x==0.0?"equal":"different");

return 0;
}

>> Does this also apply to comparisons to constants?
>> if ( f <= 1.0){

Since at least one of the two objects being compared cannot be a
constant, yes. Obviously you're a bit safer with lessthan/morethan but
you could still be surprised - delta can be both positive and negative
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

 pete 12-03-2005 03:13 PM

Re: Regarding Q. 14-5

Mark McIntyre wrote:
>
> On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
> <pfiland@mindspring.com> wrote:
>
> >Brian Dude wrote:
> >>
> >> Hello, I understand the part
> >> about not comparing two floating-point
> >> numbers for exact-ness.

> >
> >Your example doesn't show it.
> >There's nothing wrong with comparing two doubles
> >with a relational operator.

>
> Except that even when equal as far as expectation is concerned, they
> might compare unequal.

> printf("%s\n", x==0.0?"equal":"different");

== is an equality operator.
== is not a relational operator.

> >> Does this also apply to comparisons to constants?
> >> if ( f <= 1.0){

<= is a relational operator.
<= is not an equality operator.

--
pete

 Malcolm 12-03-2005 07:54 PM

Re: Regarding Q. 14-5

"Brian Dude" <noSpam@hotSPAM.com> wrote
> Hello, I understand the part about not comparing two floating-point
> numbers for exact-ness. Does this also apply to comparisons to constants?
> i.e.:
>
> double f;
>
> if ( f <= 1.0){
> ...
> }
>

That is dangerous.
f may be mathematically equal to 1, but slightly bigger because of floating
point unit errors (eg if it is the length of a unit vector, calculated with
a call to sqrt()).

 Eric Sosman 12-03-2005 08:09 PM

Re: Regarding Q. 14-5

Malcolm wrote:

> "Brian Dude" <noSpam@hotSPAM.com> wrote
>
>>Hello, I understand the part about not comparing two floating-point
>>numbers for exact-ness. Does this also apply to comparisons to constants?
>>i.e.:
>>
>>double f;
>>
>>if ( f <= 1.0){
>>...
>>}
>>

>
> That is dangerous.
> f may be mathematically equal to 1, but slightly bigger because of floating
> point unit errors (eg if it is the length of a unit vector, calculated with
> a call to sqrt()).

Malcolm raises an important problem, but does not show
how to solve it. The solution is to compare not to 1.0 but
to 1.0 plus a suitable error tolerance:

if ( f <= 1.0 + epsilon )

Unfortunately, this is just as dangerous as the original,
because f might be mathematically equal to 1+epsilon but
slightly bigger because of floating point errors. To allow
for that possibility, the test should be written as

if ( f <= 1.0 + 2.0 * epsilon )

This is still dangerous, because f might be mathematically
equal to 1+2*epsilon but slightly bigger because of floating
point errors. The same objection applies to 1+N*epsilon for
any finite N, so the only recourse is to allow for a possibly
infinite amount of inaccuracy in the floating-point calculation:

#include <math.h>
...
if (f <= 1.0 + INFINITY )

This solution should meet Malcolm's objections.

--
Eric Sosman
esosman@acm-dot-org.invalid

 Flash Gordon 12-03-2005 08:25 PM

Re: Regarding Q. 14-5

Eric Sosman wrote:
> Malcolm wrote:
>
>> "Brian Dude" <noSpam@hotSPAM.com> wrote
>>
>>> Hello, I understand the part about not comparing two floating-point
>>> numbers for exact-ness. Does this also apply to comparisons to
>>> constants?
>>> i.e.:
>>>
>>> double f;
>>>
>>> if ( f <= 1.0){
>>> ...
>>> }
>>>

>>
>> That is dangerous.
>> f may be mathematically equal to 1, but slightly bigger because of
>> floating point unit errors (eg if it is the length of a unit vector,
>> calculated with a call to sqrt()).

>
> Malcolm raises an important problem, but does not show
> how to solve it. The solution is to compare not to 1.0 but
> to 1.0 plus a suitable error tolerance:
>
> if ( f <= 1.0 + epsilon )

<snip>

You forgot the possibility that f may be mathematically slightly bigger
than 1.0 but due to floating point errors be slightly smaller, to avoid
this you should do:
if (f <= 1.0-epsilon) {
/* it's smaller or equal */
}
else if (f <= 1.0+epsilon) {
/* not sure */
}
else {
/* it's larger */
}

> #include <math.h>
> ...
> if (f <= 1.0 + INFINITY )
>
> This solution should meet Malcolm's objections.

Then following through with your argument we get:
if (f <= 1.0-INFINITY ) {
/* it's smaller or equal */
}
else if (f <= 1.0+INFINITY) {
/* not sure */
}
else {
/* it's larger */
}

:-)
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.

 Mark McIntyre 12-03-2005 09:02 PM

Re: Regarding Q. 14-5

On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
<esosman@acm-dot-org.invalid> wrote:

> Malcolm raises an important problem, but does not show
>how to solve it.

Eric raises an important problem with any solution, but fails to show
how to solve it :-)

The solution is indeed to compare to 1+epsilon, but to define epsilon
suitably for your application. Its likely for instance that if you're
doing calcs that involve rounding to 5dp, then a comparison to 4dp
will succeed. If you're doing the sum I did earlier, then epsilon
could be 1e-10 and that'd be successful.

The precise method of determining epsilon is left as an exercise for
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----

 Dik T. Winter 12-03-2005 11:02 PM

Re: Regarding Q. 14-5

In article <O6ednUWwWdAdZgzenZ2dnUVZ_sqdnZ2d@comcast.com> Eric Sosman <esosman@acm-dot-org.invalid> writes:
> Malcolm wrote:

[ About f <= 1.0 ]
> > That is dangerous.
> > f may be mathematically equal to 1, but slightly bigger because of
> > floating point unit errors (eg if it is the length of a unit vector,
> > calculated with a call to sqrt()).

In that case we have a false negative.

> Malcolm raises an important problem, but does not show
> how to solve it. The solution is to compare not to 1.0 but
> to 1.0 plus a suitable error tolerance:
> if ( f <= 1.0 + epsilon )
> Unfortunately, this is just as dangerous as the original,
> because f might be mathematically equal to 1+epsilon but
> slightly bigger because of floating point errors.

This is different. We want to compare with 1.0, and add epsilon toe
avoid false negatives. But in this case we get a true negative.
On the other hand, if f is mathematially greater than 1+epsilon,
but slightly smaller due to floating point errors we get a false
positive...

But indeed, comparing to 1.0 + epsilon is just as silly as comparing
to plain 1.0. The bottom line is that when you want to use
floating-point you better know what you are doing so that you can
judge how you wish to compare. (In all my years of programming in
numerical mathematics I rarely, if at all, coded a line like
f <= 1.0 + epsilon, but many lines like f <= 1.0.)
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

All times are GMT. The time now is 02:14 AM.