473,226 Members | 1,548 Online

# 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
Dec 3 '05 #1
30 1485
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){
...
}

--
pete
Dec 3 '05 #2
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)

would be bad, because:
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.
Dec 3 '05 #3
On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
<pf*****@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.

#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>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 3 '05 #4
Mark McIntyre wrote:

On Sat, 03 Dec 2005 06:32:03 GMT, in comp.lang.c , pete
<pf*****@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
Dec 3 '05 #5

"Brian Dude" <no****@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()).
Dec 3 '05 #6
Malcolm wrote:
"Brian Dude" <no****@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
es*****@acm-dot-org.invalid
Dec 3 '05 #7
On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
<es*****@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
the reader.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 3 '05 #8
Eric Sosman wrote:
Malcolm wrote:
"Brian Dude" <no****@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.
Dec 3 '05 #9
Mark McIntyre wrote:
On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
<es*****@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
the reader.

What I was trying to point out is that the supposed
"solution" is no solution at all. For example,

if ( f <= 1.0 )
angle = asin(f);

is not improved by replacing 1.0 with 1.0+epsilon ...

The solution -- to the degree that one exists -- is
to use care in calculating f in the first place, and to
understand the nature of the errors that occur along the
way and the manner in which they grow and decay. That
field of study is called Numerical Analysis, and is too
rich a topic to be treated at any depth in Usenet postings.

However, the fact that floating-point numbers are usually
(but not always!) approximations and that floating-point
calculations usually (but not always!) involve error should
not be taken as meaning that all floating-point comparisions
are "dangerous!"

I once read (but cannot now find) a description of a
progression of attitudes that may apply here:

1. Initially, people trust every digit of every number
a computer calculates.

2. Having learned that some (even many) digits can be
incorrect, the once-burned-twice-shy crowd overreacts
by never trusting any floating-point calculation.

3. With further experience and study, a more rational
(pun intentional) attitude of tolerance (ditto)
eventually develops. Floating-point arithmetic is
imperfect (as is int arithmetic) but like many other
tools is useful if handled with care.

It seems to me that someone whose alarm bells clang at `f<=1.0'
may not have completed the journey from stage 2 to 3. Malcolm
is probably at 2+epsilon or 3-delta, but afraid to calculate the
remaining distance ;-)

Recommended (strongly recommended) reading: "What Every
Computer Scientist Should Know About Floating-Point Arithmetic"
by David Goldberg, widely archived on the Web.

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 3 '05 #10
On Sat, 03 Dec 2005 18:29:30 -0500, in comp.lang.c , Eric Sosman
<es*****@acm-dot-org.invalid> wrote:

What I was trying to point out is that the supposed
"solution" is no solution at all.
I realise that, but my point is that you're wrong. :-)
For example,

if ( f <= 1.0 )
angle = asin(f);

is not improved by replacing 1.0 with 1.0+epsilon ...
Of course it is. You just need to choose epsilon carefully, and decide
how to handle failures. The choice of both is highly dependent on how
you arrived at the FP value you want to examine, and how you want to
handle the problem cases.

#define EPS -1e-12

if ( f <= 1.0+EPS )
angle = asin(f);
else
{
puts("f ->1");
f = asin(1.0);
}
Recommended (strongly recommended) reading: "What Every
Computer Scientist Should Know About Floating-Point Arithmetic"
by David Goldberg, widely archived on the Web.

Absolutely.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 4 '05 #11
Mark McIntyre wrote:

On Sat, 03 Dec 2005 15:09:32 -0500, in comp.lang.c , Eric Sosman
<es*****@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.

It depends on what you're doing.

In the very few times that I have written code
which compares a double variable against a double constant
with either a relational operator or an equality operator,
it would be inappropriate to make use of DBL_EPSILON.
The (DBL_MAX >= x && x > 0) expression, is correct as is,
and so is the (0 != x) expression.

double sssqrt(double x)
{
if (DBL_MAX >= x && x > 0) {
const double a = x;
double b = x / 2 + 0.5;

do {
x = b;
b = (a / x + x) / 2;
} while (x > b);
} else {
if (0 != x) {
errno = EDOM;
x = HUGE_VAL;
}
}
return x;
}

In reviewing my toy math library, I've noticed that
I don't have any code which compares two double variables
with an equality operator.

All of my epsilon usage is kind of like this:

static double p_i(void)
{
unsigned n;
double p, a, b;

p = 0;
a = 3;
n = 1;
do {
a /= 9;
b = a / n;
a /= 9;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 4);
a = 2;
n = 1;
do {
a /= 4;
b = a / n;
a /= 4;
n += 2;
b -= a / n;
n += 2;
p += b;
} while (b > DBL_EPSILON / 2);
return 4 * p;
}

--
pete
Dec 4 '05 #12
In article <O6******************************@comcast.com> Eric Sosman <es*****@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/
Dec 4 '05 #13
pete wrote:
== is not a relational operator.

?
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Dec 4 '05 #14
August Karlstrom <fu********@comhem.se> writes:
pete wrote:
== is not a relational operator.

?

6.5.8 Relational operators
Syntax
1 relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression

[...]

6.5.9 Equality operators
Syntax
1 equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression

--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Dec 4 '05 #15
On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
Mark McIntyre wrote:
The solution is indeed to compare to 1+epsilon, but to define epsilon
suitably for your application.

it would be inappropriate to make use of DBL_EPSILON.

Note carefully that I did not say DBL_EPSILON.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 4 '05 #16
Mark McIntyre wrote:

On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
Mark McIntyre wrote:
The solution is indeed to compare
to 1+epsilon, but to define epsilon
suitably for your application.

it would be inappropriate to make use of DBL_EPSILON.

Note carefully that I did not say DBL_EPSILON.

I would say that in cases
where a suitable definition of epsilon, is zero,
that the use of epsilon isn't required.

--
pete
Dec 4 '05 #17
Ben Pfaff wrote:
August Karlstrom <fu********@comhem.se> writes:

pete wrote:
== is not a relational operator.

?

6.5.8 Relational operators
Syntax
1 relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression

[...]

6.5.9 Equality operators
Syntax
1 equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression

OK, that's weird. Still `==' works as a relational operator in the
common (mathematical) sense.
August

--
I am the "ILOVEGNU" signature virus. Just copy me to your
signature. This email was infected under the terms of the GNU
General Public License.
Dec 4 '05 #18
August Karlstrom wrote:

Ben Pfaff wrote:
August Karlstrom <fu********@comhem.se> writes:

pete wrote:

== is not a relational operator.

?
6.5.8 Relational operators 6.5.9 Equality operators
OK, that's weird. Still `==' works as a relational operator in the
common (mathematical) sense.

I wrote what I wrote, plainly:

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

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

--
pete
Dec 4 '05 #19
August Karlstrom wrote:
Ben Pfaff wrote:
August Karlstrom <fu********@comhem.se> writes:

pete wrote:

== is not a relational operator.

?

6.5.8 Relational operators
Syntax
1 relational-expression:
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression

[...]

6.5.9 Equality operators
Syntax
1 equality-expression:
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression

OK, that's weird. Still `==' works as a relational operator in the
common (mathematical) sense.

Yes, it's a nice gotcha, isn't it? Like "byte", this is one of those terms C
appropriates in its own way and doesn't quite mean what you'd expect it to mean.

S.
Dec 4 '05 #20
On Sun, 04 Dec 2005 13:59:20 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
Mark McIntyre wrote:

On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
>Mark McIntyre wrote:
>
>> The solution is indeed to compare
>> to 1+epsilon, but to define epsilon
>> suitably for your application.
>
>it would be inappropriate to make use of DBL_EPSILON.

Note carefully that I did not say DBL_EPSILON.

I would say that in cases
where a suitable definition of epsilon, is zero,
that the use of epsilon isn't required.

zero is certainly one possible definition of epsilon. You're pretty
much making my point.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 4 '05 #21
Mark McIntyre wrote:
On Sun, 04 Dec 2005 13:59:20 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:

Mark McIntyre wrote:
On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:
Mark McIntyre wrote:
>The solution is indeed to compare
>to 1+epsilon, but to define epsilon
>suitably for your application.

it would be inappropriate to make use of DBL_EPSILON.

Note carefully that I did not say DBL_EPSILON.

I would say that in cases
where a suitable definition of epsilon, is zero,
that the use of epsilon isn't required.

zero is certainly one possible definition of epsilon. You're pretty
much making my point.

Your point was that the test `f <= 1.0' is "dangerous."
As far as I can tell, everyone else on the thread rejects
this point as invalid. You yourself reject it when you
accept a zero epsilon as suitable.

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 4 '05 #22
pete wrote:
Mark McIntyre wrote:
On Sat, 03 Dec 2005 23:59:57 GMT, in comp.lang.c , pete
<pf*****@mindspring.com> wrote:

Mark McIntyre wrote:
The solution is indeed to compare
to 1+epsilon, but to define epsilon
suitably for your application.

it would be inappropriate to make use of DBL_EPSILON.

Note carefully that I did not say DBL_EPSILON.

I would say that in cases
where a suitable definition of epsilon, is zero,
that the use of epsilon isn't required.

I may be slightly off-point here in which case, I apologize.

I calculate cos(pi/2) and get 6.1232339957367660e-17 which if very
nearly zero. But not quite. How can I use DBL_EPSILON to determine that
it is, for practical purposes, zero.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Dec 4 '05 #23
On Sun, 04 Dec 2005 11:41:40 -0500, in comp.lang.c , Eric Sosman
<es*****@acm-dot-org.invalid> wrote:
Your point was that the test `f <= 1.0' is "dangerous."
Clearly you missed my point. Which was that you erroneously stated
that you can't meaningfully use an epsilon. This is, as I'm sure
you're aware, garbage.
As far as I can tell, everyone else on the thread rejects
this point as invalid. You yourself reject it when you
accept a zero epsilon as suitable.

Seemingly you aren't actually reading what I'm writing, you're just
responding to my criticism of you by attacking me. Your problem, not
mine.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 4 '05 #24
On Sun, 04 Dec 2005 12:12:01 -0500, in comp.lang.c , Joe Wright
<jw*****@comcast.net> wrote:
I calculate cos(pi/2) and get 6.1232339957367660e-17 which if very
nearly zero. But not quite. How can I use DBL_EPSILON to determine that
it is, for practical purposes, zero.

You could just say that if the result was less than DBL_EPSILON, then
it was zero. DBL_EPSILON isn't really designed for this though.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 4 '05 #25
Mark McIntyre wrote:
On Sun, 04 Dec 2005 11:41:40 -0500, in comp.lang.c , Eric Sosman
<es*****@acm-dot-org.invalid> wrote:

Your point was that the test `f <= 1.0' is "dangerous."

Clearly you missed my point. Which was that you erroneously stated
that you can't meaningfully use an epsilon. This is, as I'm sure
you're aware, garbage.

As far as I can tell, everyone else on the thread rejects
this point as invalid. You yourself reject it when you
accept a zero epsilon as suitable.

Seemingly you aren't actually reading what I'm writing, you're just
responding to my criticism of you by attacking me. Your problem, not
mine.

A thousand apologies: Indeed, I misread what you wrote.
Searching up-thread I see that it was not you but Malcolm
who claimed that `f <= 1.0' is "dangerous," and it's that
rash claim I've been disputing.

Once again, sorry for my mistake.

--
Eric Sosman
es*****@acm-dot-org.invalid
Dec 4 '05 #26
On Sun, 04 Dec 2005 13:49:54 -0500, in comp.lang.c , Eric Sosman
<es*****@acm-dot-org.invalid> wrote:
Once again, sorry for my mistake.

Equally sorry if I was rude in my last posting.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 5 '05 #27
In article <mq********************************@4ax.com> Mark McIntyre <ma**********@spamcop.net> writes:
....
#define EPS -1e-12

if ( f <= 1.0+EPS )
angle = asin(f);
else
{
puts("f ->1");
f = asin(1.0);
}

And how do you explain to the user of this fragment that a domain error
is encountered in asin?
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Dec 5 '05 #28
On Mon, 5 Dec 2005 02:42:40 GMT, in comp.lang.c , "Dik T. Winter"
<Di********@cwi.nl> wrote:
In article <mq********************************@4ax.com> Mark McIntyre <ma**********@spamcop.net> writes:
...
#define EPS -1e-12

if ( f <= 1.0+EPS )
angle = asin(f);
else
{
puts("f ->1");
f = asin(1.0);
}

And how do you explain to the user of this fragment that a domain error
is encountered in asin?

And when does it do that? Read what I wrote more carefully.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== 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 =----
Dec 5 '05 #29

"Dik T. Winter" <Di********@cwi.nl> wrote
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.)

If you compare to 1.0 + epsilon you exclude the false negatives (since the
real value we are interested in is 1.0, not 1.0 + epsilon). If you compare
to 1.0 - epsilon you exclude the false positives.
When f is in the range 1 +/- epsilon we have a problem. It depends what you
expect f to be th result of, and why you are making the comparison.

Let's say that you are writng some sort of lighting algorithm that requires
vetors to be either normalised or scaled to be under 1. If you want to
exclude / trap any unnormalised vectors, you probably expect most of the
vectors to be the result of dividing by a square root, and thus
mathematically unity. You probably want to accept any a whisker over 1.0 in
length.

On the other hand if f is a probability, you probably wnat to compare to a
hard 1.0 - p might easily be exactly 1.0, but if it is a whisker over that
probably represents something bad elsewhere.

Unfortunately there aren't any hard or fast rules.

Dec 7 '05 #30
"Eric Sosman" <es*****@acm-dot-org.invalid> wrote
Seemingly you aren't actually reading what I'm writing, you're just
responding to my criticism of you by attacking me. Your problem, not
mine.

A thousand apologies: Indeed, I misread what you wrote.
Searching up-thread I see that it was not you but Malcolm
who claimed that `f <= 1.0' is "dangerous," and it's that
rash claim I've been disputing.

Once again, sorry for my mistake.

Gas heaters are also dangerous. People die of carbon monoxide poisoning
every year.

Unfortunately there's not much you can do about it - no one has yet built a
practical CO monitor. Banning gas would mean the loss of an entire fuel
source. "Dangerous" and "unusable" are two different things.

As for your point that, if we test against 1 + epislon it doesn't do any
good unless we also test agaisnt 1 + epsilon * 2, I hope you can see the
fallacy of this.
We are interested in numbers mathematically equal to or less than unity.
Testing against 1.0 + episilon gets rid of all the false rejections, at the
price of risking more false acceptances. That may be good or bad, depending
on which is worse for your particular program.

Dec 11 '05 #31

This thread has been closed and replies have been disabled. Please start a new discussion.

### Similar topics

 1 by: praba kar | last post by: Dear All, I have doubt regarding headers in cgi programming. If I gives "Content-Type:text/plain" then I try to print html contents. Is right or wrong after giving content-type: text/plain?... 25 by: Steal | last post by: Hi at all I try to validate this page using the link: http://validator.w3.org/ but it return that this is not a valid HTML 4.01 page please where is it error? Steil main() { int x=10,y; y=sizeof(++x); printf("x=%d\ny=%d\n",x,y); } Oput Put 10 by: Rob | last post by: I am reading a book that says that the "name" property can be altered only at design time and cannot be modified at runtime. Please explain this given the code below... If you click Button3...... 14 by: somenath | last post by: Hi All, I am trying to understand the behavior of the memcpy and memmove. While doing so I wrote a program as mentioned bellow . #include #include #include ... 17 by: somenath | last post by: Hi All, I have one question regarding the bellow mentioned code #include int main(void) { int x = 0; int y = 0; 3 by: somenath | last post by: Hi All, I have one question regarding the conditional operator. In the draft C99 standard it is mentioned that "1 The following are the sequence points described in 5.1.2.3: -- The call to a... 1 by: Tomohiro Kusumi | last post by: Hi, I have a question regarding re module. # By the way I'm not in this list, so I'm sorry but please CC me. I tried following code in Python shell using a regular expression. Why doesn't the... 3 by: Michel Esber | last post by: Hi all, DB2 V8 LUW FP 15 There is a table T (ID varchar (24), ABC timestamp). ID is PK. Our application needs to frequently update T with a new value for ABC. update T set ABC=? where ID... 1 by: isladogs | last post by: The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike... 0 by: VivesProcSPL | last post by: Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for... 0 by: jianzs | last post by: Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from... 0 by: mar23 | last post by: Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the... 2 by: jimatqsi | last post by: The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art... 2 by: isladogs | last post by: The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE... 0 by: egorbl4 | last post by: Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ... 1 by: davi5007 | last post by: Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the... 0 by: MeoLessi9 | last post by: I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.