checking if a number is zero within machine precision

H

H.S.

Hello,

I am trying out a few methods with which to test of a given number is
practically zero. as an example, does the following test correctly if a
given number is zero within machine precision? I am trying out this
method to check for a practical zero in an algorithm I am implementing
in C++.
-------------------------
#include <iostream>
#include <iomanip>
#include <limits>
#include <cmath>

int main(int argc, char ** argv){
if (argc != 2){
std::cerr << "No number given, quitting\n";
exit(-1);
}
double num = std::atof(argv[1]);
std::cout << std::numeric_limits<double>::epsilon() << std::endl;

if (std::fabs(num) < std::numeric_limits<double>::epsilon())
std::cout << "Numer is practically zero\n";
else
std::cout << "Number is non-zero\n";

return 0;
}
-------------------------

Here is a test run:
$> g++ -Wall -ansi myeps.cc -o myeps -lm
$> ./myeps 1e-15
2.22045e-16
Number is non-zero

thanks,
->HS
 
V

Victor Bazarov

H.S. said:
I am trying out a few methods with which to test of a given number is
practically zero.

What's your definition of "zero"?
as an example, does the following test correctly if
a given number is zero within machine precision?

According to what defintion of "zero"? It tests if a given number is
below the "machine zero", which is the largest number that does not
change 1 if added to it, IOW, "machine zero" (eps): 1.0 + eps == 1.0
(or, in some definitions the machine zero is the smallest number that
when added to 1 actually changes it, eps: 1.0 + eps != 1.0). You have
to give your definition (even if it's just "use the machine zero").
I am trying out this
method to check for a practical zero in an algorithm I am implementing
in C++.

It all comes down to _your_ definition of "practical zero". For all we
know when it comes to placing a car on a city map, plus or minus one
foot does not really matter, so a foot is the "practical zero". But,
when manufacturing computer components, for example, a foot would be
a really large distance, and cannot be seen as "practical zero".

Catch my drift?
-------------------------
#include <iostream>
#include <iomanip>
#include <limits>
#include <cmath>

int main(int argc, char ** argv){
if (argc != 2){
std::cerr << "No number given, quitting\n";
exit(-1);
}
double num = std::atof(argv[1]);
std::cout << std::numeric_limits<double>::epsilon() <<
std::endl;

if (std::fabs(num) < std::numeric_limits<double>::epsilon())
std::cout << "Numer is practically zero\n";
else
std::cout << "Number is non-zero\n";

return 0;
}
-------------------------

Here is a test run:
$> g++ -Wall -ansi myeps.cc -o myeps -lm
$> ./myeps 1e-15
2.22045e-16
Number is non-zero

thanks,
->HS

V
 
H

H.S.

Victor said:
What's your definition of "zero"?


According to what defintion of "zero"? It tests if a given number is
below the "machine zero", which is the largest number that does not
change 1 if added to it, IOW, "machine zero" (eps): 1.0 + eps == 1.0

Okay. Lets take this definition of zero you gave above.

->HS
 
V

Victor Bazarov

H.S. said:
Okay. Lets take this definition of zero you gave above.

If you take that definition, you got your epsilon already. Keep in
mind that it doesn't necessarily fit the problem domain (which you
didn't mention at all). Consider also asking about those things in
'sci.math.num-analysis'.

V
 
J

Jerry Coffin

Hello,

I am trying out a few methods with which to test of a given number is
practically zero. as an example, does the following test correctly if a
given number is zero within machine precision? I am trying out this
method to check for a practical zero in an algorithm I am implementing
in C++.

Testing for near equality of two floating point numbers is a rather
tricky operation at best. The case you've given (one of the numbers is
zero) is an especially tricky case.

When you have two floating point numbers, and want to figure out whether
they're practically equal, you normally want to find the magnitudes of
the numbers, then use that magnitude to scale epsilon to figure out the
smallest difference that can be represented between numbers of that
magnitude. You then decide on the tolerance you'll allow (i.e. your
estimate of approximately how much rounding error your calculations may
have introduced) and multiply the scaled magnitude by that. Then you
check whether the absolute difference between the numbers falls within
that range or not.

Depending on the magnitudes of the numbers you started with, 1e-100
might be so large it means a lot, or it might be so small that it's
meaningless. For example, if you have 1.1e-100 and 1.0e-100, they're
probably not equal. While the absolute difference is about 1e-101, the
relative difference is about 10%, which is more than you'd expect to see
as rounding error from most calculations.

By contrast, 1.000000000000000001e-70 and 1.00000000000000002e-70
probably are practically equal. The absolute difference between the two
numbers is much larger than in the case above (about 1e-88 if I've
counted correctly), but the relative difference is _much_ smaller -- a
single bit about 18 places after the decimal point. This is often close
to the limit of the smallest difference that can be represented, so even
the slightest roundoff error in the calculation could lead to a
difference this large.

Attempting to compare to zero, however, means we no longer have the
magnitudes of the two numbers to guide us in guessing how much rounding
error we might expect. The only way the operation can be made meaningful
is by providing an explicit statement of the value below which we
consider the number "practically" zero. If we were to assume that one
range of numbers was as likely as any other, that value would be epsilon
about once ot of 1e309 times (or so). In reality, epsilon probably is
rightt more often than that, but only a little bit more often.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top