472,980 Members | 1,716 Online

# floating point problems

Hello,

I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

Thanks

Feb 2 '06 #1
27 2085
"G Patel" <ga********@gmail.com> wrote in message
I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

It ain't easy. What you need is a well written hypot function
from C99. Barring that, take a look at the (template) function
_Fabs in the header xcomplex in our Standard C++ library. It
computes the magnitude of a complex number, which is the same
problem as you have. Reading it is tough sledding, but it's
the minimum you have to do to preserve all those bits you need.

Alternatively, I suspect there's some way to recast your problem
to an atan2 call, if all you really care about is right-angle
detection.

HTH,

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Feb 2 '06 #2

"P.J. Plauger" <pj*@dinkumware.com> wrote in message
news:pJ******************************@giganews.com ...
"G Patel" <ga********@gmail.com> wrote in message
I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

It ain't easy. What you need is a well written hypot function
from C99.

I'm not sure if it's C99, but there is a hypot function in Sun Microsystem's
Freely Distributable LIBM:
http://www.netlib.org/fdlibm/

Rod Pemberton
Feb 2 '06 #3

Rod Pemberton wrote:
"P.J. Plauger" <pj*@dinkumware.com> wrote in message
news:pJ******************************@giganews.com ...
"G Patel" <ga********@gmail.com> wrote in message
I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

It ain't easy. What you need is a well written hypot function
from C99.

I'm not sure if it's C99, but there is a hypot function in Sun Microsystem's
Freely Distributable LIBM:
http://www.netlib.org/fdlibm/

Thanks.

Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

Any idea what this -0.0000 ? How can I compare that to 0?

Thanks

Feb 2 '06 #4
G Patel wrote:
Hello,

I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 19 999 98.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

Thanks

don't rely on the printing... with
printf ("dist ((%d, %d), (%d, %d)) == %14.8f\n", x1, y1, x2, y2, d);
i'va got the rigth result
dist ((0, 0), (1, 1999998)) == 1999998.00000025

Xavier
Feb 2 '06 #5
"G Patel" <ga********@gmail.com> wrote:
Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

It looks like you are calculating a square root, and then you take the
result and square it immediately. That is a bit pointless, isn't it?
Just takes code and execution time and adds a bit of rounding error.
Better write a function that returns the square of the distance between
two points.
Feb 2 '06 #6

G Patel wrote On 02/02/06 18:01,:
[...]

Thanks.

Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

Any idea what this -0.0000 ? How can I compare that to 0?

It's a negative value whose magnitude is less
than half a ten-thousandth -- that is, it't a small
negative number that looks like zero when rounded
to four decimal places. Perhaps it's -0.00000312
or some such.

When comparing floating-point numbers, it is
usually a poor idea to check for exact equality.
F-P numbers should be regarded as approximations,
so rather than test for "equal" you should usually
test for "close enough." You should probably do
something like

if (fabs(result) < TOLERANCE) {
/* it's a right triangle, as near as
I can tell */
}
else {
/* it's definitely not a right triangle */
}

The test itself is simple, but choosing a good value
for TOLERANCE can be extraordinarily difficult.

comp.lang.c Frequently Asked Questions (FAQ) list at

http://www.c-faq.com/

--
Er*********@sun.com

Feb 2 '06 #7
"G Patel" <ga********@gmail.com> writes:
[...]
Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

Any idea what this -0.0000 ? How can I compare that to 0?

How did you print it? If you used printf's "%f" format, anything
sufficiently close to 0.0 will appear as either -0.000000 or 0.000000.
Use the "%e" or "%g" format to get a better idea of the actual value,
and specify extra precision to get an even better idea:

#include <stdio.h>
int main(void)
{
double x = -1.2345e-67;
double y = +1.2345e-67;
printf("x = %f, y = %f\n", x, y);
printf("x = %g, y = %g\n", x, y);
printf("x = %.20g, y = %.20g\n", x, y);
return 0;
}

Floating-point numbers are inexact. See section 14 of the
comp.lang.c FAQ, <http://www.c-faq.com/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 2 '06 #8
On 2 Feb 2006 15:01:21 -0800, in comp.lang.c , "G Patel"
<ga********@gmail.com> wrote:

Any idea what this -0.0000 ? How can I compare that to 0?

Welcome to the Real World (tm), where maths is not exact.

Due to how computers store numbers, reals cannot generally be stored
precisely. Thus your maths has resulted in a number nearly (but not
quite) zero, lets say 1e-16. Google for "goldberg floating point" for
more detail.

As I'm sure you realise this makes it impossible in general terms to
compare floating point numbers. What you do instead is define some
EPSILON which is 'close enough' and compare the difference to that.

Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== 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 =----
Feb 2 '06 #9

G Patel wrote:
Hello,

I'm having trouble with floating point problems.

I'm trying to write a function that calculates the distance between two
cartesian points (integer coordinates). I have the function working,
but it fails on one test case.

Here is my function:

double
distance(int x1, int y1, int x2, int y2)
{
double deltax = (double)x1 - x2;
double deltay = (double)y1 - y2;
return sqrt(deltax*deltax + deltay*deltay);
}
It works fine for most cases except that if deltax is really small
compared to deltay (or vice versa), the addition inside the sqrt
argument causes the smaller square value to be lost (because of adding
a large float number with a small float number)).

example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?
Let's see ... what you need looks something like this:

#include <errno.h>
#include <math.h>

double
hypot(double x, double y)
{
int errx = fpclassify (x);
int erry = fpclassify (y);
double fabsx, fabsy, z;

/* Inf takes precedence over NaN ... strange */
if (errx == FP_INFINITE || erry == FP_INFINITE)
{
errno = ERANGE;
return HUGE_VAL;
}
else if (errx == FP_NAN || erry == FP_NAN)
{
errno = EDOM;
return (errx == FP_NAN) ? x : y;
}
fabsx = x < 0.0 ? -x : x;
fabsy = y < 0.0 ? -y : y;
if (errx == FP_ZERO || erry == FP_ZERO)
{
if (errx == FP_ZERO && erry == FP_ZERO)
return +0.0;
else
return (errx == FP_ZERO) ? fabsy : fabsx;
}
else
{
if (fabsx > fabsy)
{
z = fabsy / fabsx;
return fabsx * sqrt (1.0 + z * z);
}
else
{
z = fabsx / fabsy;
return fabsy * sqrt (1.0 + z * z);
}
}
}

Thanks

HTH, HAND, Gregory Pietsch

Feb 3 '06 #10

Christian Bau wrote:
"G Patel" <ga********@gmail.com> wrote:
Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

It looks like you are calculating a square root, and then you take the
result and square it immediately. That is a bit pointless, isn't it?
Just takes code and execution time and adds a bit of rounding error.
Better write a function that returns the square of the distance between
two points.

My hands are tied because I have to use the distance function's
distances inside my right triangle function.

Feb 3 '06 #11
"Gregory Pietsch" <GK**@flash.net> wrote:
double
hypot(double x, double y)
{
int errx = fpclassify (x);
int erry = fpclassify (y);
double fabsx, fabsy, z;

/* Inf takes precedence over NaN ... strange */
if (errx == FP_INFINITE || erry == FP_INFINITE)
{
errno = ERANGE;
return HUGE_VAL;
}
else if (errx == FP_NAN || erry == FP_NAN)
{
errno = EDOM;
return (errx == FP_NAN) ? x : y;
}
fabsx = x < 0.0 ? -x : x;
fabsy = y < 0.0 ? -y : y;
if (errx == FP_ZERO || erry == FP_ZERO)
{
if (errx == FP_ZERO && erry == FP_ZERO)
return +0.0;
else
return (errx == FP_ZERO) ? fabsy : fabsx;
}
else
{
if (fabsx > fabsy)
{
z = fabsy / fabsx;
return fabsx * sqrt (1.0 + z * z);
}
else
{
z = fabsx / fabsy;
return fabsy * sqrt (1.0 + z * z);
}
}
}

This implementation has the rather unfortunate property that there are
values x1, x2, y1, y2 such that

0 <= x1 <= x2
0 <= y1 <= y2

but

hypot (x1, y1) > hypot (x2, y2)

To see how this happens: Choose y1 = y2 = 1. Start with x = 1.99. The
function will calculate z = 1.0 / x, then tmp = sqrt (1.0 + z*z), then
finally return x * tmp. z will be around 0.5, tmp will be about 1.12.

Let u be the difference between x and the next larger floating point
number. If you do the same calculation with x+u, x+2u, x+3u etc. instead
of x, the value of z will eventually become smaller by u, so we can find
values x1, x2 such that x2 = x1 + u and tmp (x2) = tmp (x1) - u. In that
case the product fabsx * sqrt (1.0 + z * z), where sqrt (1.0 + z * z)
was calculated with double precision, will actually become smaller. Due
to the rounding of the result, the result will not always become
smaller, but sometimes it will become smaller when x is made larger.

I also suspect that you will not get the correctly rounded result in
some trivial cases like hypot (5.0, 12.0) which should be exactly equal
to 13.0.

You get a better and faster result as follows:

1. Calculate z = x*x + y*y. Make sure that the implementation doesn't
use fused multiply-add instructions for this; otherwise it can happen
that hypot (x, y) != hypot (y, x) which would be unfortunate.

2. Check that the result of z did not overflow, but also check that it
is large enough to guarantee that either none of the products x*x and
y*y did underflow, or that the other product is so large that it doesn't
make a difference. If both conditions are true, return sqrt (z).

3. If the result of z did overflow, you can find a constant c which is a
power of two so that c * sqrt ((x / c) * (x / c) + (y / c) * (y / c))
will give the correctly rounded result. The same can be done with a
different constant c' if the result of z was too small.
Feb 3 '06 #12
"G Patel" <ga********@gmail.com> wrote:
Christian Bau wrote:
"G Patel" <ga********@gmail.com> wrote:
Now I still have a bug happening near the end of my program. When I do
the test for right triangle, I take the difference between (hyp^2) and
the sum of the other two sides squared. Sometimes this results in the
floating point value -0.00000 (i checked by printing it out). When I
compare the result with 0.0 it fails.

It looks like you are calculating a square root, and then you take the
result and square it immediately. That is a bit pointless, isn't it?
Just takes code and execution time and adds a bit of rounding error.
Better write a function that returns the square of the distance between
two points.

My hands are tied because I have to use the distance function's
distances inside my right triangle function.

If it is a homework problem, tell your instructor that his method is
stupid. If it is not a homework problem, your hands are not tied.

If you are given three points (x0, y0), (x1, y1), and (x2, y2), the
easiest way to determine whether there is a right angle at (x0, y0) is
the following:

Subtract (x0, y0) from (x1, y1) and (x2, y2), so the whole triangle is
moved to bring the first point to (0, 0)

x1 -= x0; y1 -= y0;
x2 -= x0; y2 -= y1;

Then all you do is to check whether

x1*y1 == - x2*y2

If they are the same, you have a right angle. If they are not the same,
you don't have a right angle. That's all.
Feb 3 '06 #13

Christian Bau wrote:
"G Patel" <ga********@gmail.com> wrote:
Christian Bau wrote:
"G Patel" <ga********@gmail.com> wrote:

> Now I still have a bug happening near the end of my program. When I do
> the test for right triangle, I take the difference between (hyp^2) and
> the sum of the other two sides squared. Sometimes this results in the
> floating point value -0.00000 (i checked by printing it out). When I
> compare the result with 0.0 it fails.

It looks like you are calculating a square root, and then you take the
result and square it immediately. That is a bit pointless, isn't it?
Just takes code and execution time and adds a bit of rounding error.
Better write a function that returns the square of the distance between
two points.

My hands are tied because I have to use the distance function's
distances inside my right triangle function.

If it is a homework problem, tell your instructor that his method is
stupid. If it is not a homework problem, your hands are not tied.

It is a school assignment and I have the program working except that
our programs are testing automatically by some program.

He lets us know 8 of the cases, the rest are hidden. 2 of the cases
seem impossible to implement in computers (and yes, we have to sqrt in
a distance function, and then resquare it in the actualy "figuring out"
function).

One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).

The other case has a triangle with 2 really large sides and one very
small sides. He wants us to get it within some tolerance, but i can't
seem to "keep" the information from the small side to "stick" within
the sqrt function.

I am going to email him and tell him that his cases are ridiculous (in
a nice way).

Thanks.

Feb 3 '06 #14
Op 2 Feb 2006 16:58:41 -0800 schreef G Patel:
One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).

<OT>
This is a rectacngular triangle with sides 4, 5 and sqrt(41).
</OT>
--
Coos
Feb 3 '06 #15
Coos Haak <ch*****@hccnet.nl> writes:
Op 2 Feb 2006 16:58:41 -0800 schreef G Patel:
One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).

<OT>
This is a rectacngular triangle with sides 4, 5 and sqrt(41).
</OT>

This is usually referred to as a "right triangle", not a "rectangular
triangle". ("rectangular" refers to a 4-sided polygon all of whose
vertices are 90 degress.)

But if a test case provides a triangle one of whose sides is merely *a
close approximatation to* sqrt(41), it's foolish to expect an exact
result.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 3 '06 #16
G Patel wrote:

I'm having trouble with floating point problems.
.... snip ...
example: deltax = 1 deltay = 1999998

What this distance function returns is exactly what would be returned
if only one of the dimensions were 1999998.

This is crucial because I need the distance formula to work within a
certain tolerance so I can check to see if triangles are right or
oblique.

Does anyone know any tricks that I can use to preserve the "effect" of
the small deltax in the distance?

Welcome to the world of floating point. They are intrinsically
inexact. You have to learn to analyze the errors. A good
reference is Knuths TAOCP.

Please make sure you read the references in my sig. below BEFORE
posting again.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
Feb 3 '06 #17
Mark McIntyre <ma**********@spamcop.net> wrote:
On 2 Feb 2006 15:01:21 -0800, in comp.lang.c , "G Patel"
<ga********@gmail.com> wrote:
Any idea what this -0.0000 ? How can I compare that to 0?

Welcome to the Real World (tm), where maths is not exact.

Actually, that's the problem. In the Real World, maths _is_ exact.
Gravity works to an infinity of decimals. It's just computers (and
similar devices) which have problems with that; the rest of the world
doesn't see the problem.

Richard
Feb 3 '06 #18
Keith Thompson wrote:
Coos Haak <ch*****@hccnet.nl> writes:
Op 2 Feb 2006 16:58:41 -0800 schreef G Patel:
One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).

<OT>
This is a rectacngular triangle with sides 4, 5 and sqrt(41).
</OT>

This is usually referred to as a "right triangle", not a "rectangular
triangle". ("rectangular" refers to a 4-sided polygon all of whose
vertices are 90 degress.)

[...]

In spanish a right triangle is called "triángulo rectángulo" which
translated literally to english would give "rectangular triangle". I
for one find that error understandable.

Feb 3 '06 #19
On 2006-02-03, Richard Bos <rl*@hoekstra-uitgeverij.nl> wrote:
Mark McIntyre <ma**********@spamcop.net> wrote:
On 2 Feb 2006 15:01:21 -0800, in comp.lang.c , "G Patel"
<ga********@gmail.com> wrote:
>Any idea what this -0.0000 ? How can I compare that to 0?
Welcome to the Real World (tm), where maths is not exact.

Actually, that's the problem. In the Real World, maths _is_ exact.

Except for quantum mechanics, the heisenberg uncertainty principle, etc
Gravity works to an infinity of decimals.
Just keep telling yourself that.
It's just computers (and similar devices) which have problems with
that; the rest of the world doesn't see the problem.

Richard

Feb 3 '06 #20
Richard Bos wrote:
Mark McIntyre <ma**********@spamcop.net> wrote:
"G Patel" <ga********@gmail.com> wrote:
Any idea what this -0.0000 ? How can I compare that to 0?

Welcome to the Real World (tm), where maths is not exact.

Actually, that's the problem. In the Real World, maths _is_
exact. Gravity works to an infinity of decimals. It's just
computers (and similar devices) which have problems with
that; the rest of the world doesn't see the problem.

Actually such men as Cantor and Dedekind resolved those inexact
maths problems well over a century ago, with rigid definitions of
limits and other inexact concepts. "When, for any epsilon, we can
find an n such that ...".

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 3 '06 #21
Op Fri, 03 Feb 2006 01:10:39 GMT schreef Keith Thompson:
Coos Haak <ch*****@hccnet.nl> writes:
Op 2 Feb 2006 16:58:41 -0800 schreef G Patel:
One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).
<OT>
This is a rectacngular triangle with sides 4, 5 and sqrt(41).
</OT>

This is usually referred to as a "right triangle", not a "rectangular
triangle". ("rectangular" refers to a 4-sided polygon all of whose
vertices are 90 degress.)

In Dutch it's 'rechthoekige driehoek' and a 'rechte driehoek' does not
exist. So it's just the other way round here ;-)
But if a test case provides a triangle one of whose sides is merely *a
close approximatation to* sqrt(41), it's foolish to expect an exact
result.

Agreed.

Coos
--
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
Feb 3 '06 #22
Coos Haak wrote:
Op Fri, 03 Feb 2006 01:10:39 GMT schreef Keith Thompson:
.... snip ...
But if a test case provides a triangle one of whose sides is
merely *a close approximatation to* sqrt(41), it's foolish to
expect an exact result.

Agreed.

But if the expression "sqrt(41)" is never evaluated it is still
possible to make exact comparisons with other quantities, such as
"sqrt(4*4 + 5*5)". As others have pointed out in this very
thread. You just have to think a little, instead of applying the
magic crank. This involves realizing that floating point values are
inherently approximations.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
Feb 3 '06 #23
On Fri, 03 Feb 2006 01:10:39 GMT, in comp.lang.c , Keith Thompson
<ks***@mib.org> wrote:
This is usually referred to as a "right triangle",

In UK English, a right-angle triangle.
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== 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 =----
Feb 3 '06 #24
On Fri, 03 Feb 2006 09:53:48 -0500, in comp.lang.c , CBFalconer
<cb********@yahoo.com> wrote:
Actually such men as Cantor and Dedekind resolved those inexact
maths problems well over a century ago, with rigid definitions of
limits and other inexact concepts. "When, for any epsilon, we can
find an n such that ...".

You mean they used rigidly defined areas of doubt and uncertainty.

Wow, deep thought indeed.

Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== 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 =----
Feb 3 '06 #25
On Fri, 03 Feb 2006 07:41:26 GMT, in comp.lang.c ,
rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
Mark McIntyre <ma**********@spamcop.net> wrote:
On 2 Feb 2006 15:01:21 -0800, in comp.lang.c , "G Patel"
<ga********@gmail.com> wrote:
>Any idea what this -0.0000 ? How can I compare that to 0?

Welcome to the Real World (tm), where maths is not exact.

Actually, that's the problem. In the Real World, maths _is_ exact.

Well, kinda. In the actual Real World, you have to use tools to do
maths and those tools are not exact. In the intellectual Real World,
maths is done in brains, and is therefore exact.

Pick a real world...
Mark McIntyre
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

----== 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 =----
Feb 3 '06 #26
"G Patel" <ga********@gmail.com> wrote:
Christian Bau wrote:
"G Patel" <ga********@gmail.com> wrote:
Christian Bau wrote:
> "G Patel" <ga********@gmail.com> wrote:
>
> > Now I still have a bug happening near the end of my program. When I
> > do
> > the test for right triangle, I take the difference between (hyp^2)
> > and
> > the sum of the other two sides squared. Sometimes this results in
> > the
> > floating point value -0.00000 (i checked by printing it out). When I
> > compare the result with 0.0 it fails.
>
> It looks like you are calculating a square root, and then you take the
> result and square it immediately. That is a bit pointless, isn't it?
> Just takes code and execution time and adds a bit of rounding error.
> Better write a function that returns the square of the distance between
> two points.

My hands are tied because I have to use the distance function's
distances inside my right triangle function.

If it is a homework problem, tell your instructor that his method is
stupid. If it is not a homework problem, your hands are not tied.

It is a school assignment and I have the program working except that
our programs are testing automatically by some program.

He lets us know 8 of the cases, the rest are hidden. 2 of the cases
seem impossible to implement in computers (and yes, we have to sqrt in
a distance function, and then resquare it in the actualy "figuring out"
function).

One of the cases has a triangle with a side that is of length sqrt(41),
which is irrational. So when the other function gets it and resquares
it, accuracy is lost. Yet his testing program wants an exactly
solution (no approximate one allowed for this case).

The other case has a triangle with 2 really large sides and one very
small sides. He wants us to get it within some tolerance, but i can't
seem to "keep" the information from the small side to "stick" within
the sqrt function.

I am going to email him and tell him that his cases are ridiculous (in
a nice way).

No, the test cases are not a problem. Putting a completely unnecessary
complication into the problem _is_ a problem.

There is a way around this. Your program started with integer values.
Each side of the triangle is the square root of an integer. If you
square it, the result is again an integer, except for rounding errors,
which means it is only close to an integer. Now you have to check whether

a*a + b*b - c*c == 0.0

or not. The squares should be integers; therefore the sum on the left
side should be an integer. It won't be an integer because of rounding
errors. Lets say you got a result of 0.01: You know you don't have the
exact result, because the exact result must be an integer. So you can
assume that the correct result is the nearest integer. To check whether
the correct result is zero, check whether the absolute value is less
than 1/2.
Feb 3 '06 #27
In article <43***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
Coos Haak wrote:
Op Fri, 03 Feb 2006 01:10:39 GMT schreef Keith Thompson:

... snip ...
But if a test case provides a triangle one of whose sides is
merely *a close approximatation to* sqrt(41), it's foolish to
expect an exact result.

Agreed.

But if the expression "sqrt(41)" is never evaluated it is still
possible to make exact comparisons with other quantities, such as
"sqrt(4*4 + 5*5)". As others have pointed out in this very
thread. You just have to think a little, instead of applying the
magic crank. This involves realizing that floating point values are
inherently approximations.

In the case at hand, it is guaranteed that square roots of integer
values are taken. The final result is a floating-point number which is
guaranteed to be an integer, except for rounding errors. You can find
the exact value if you can guarantee the rounding error is less than one
half.
Feb 3 '06 #28

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