Question

I have a program and I'm trying to calculatecos(M_PI*3/2) and instead of getting 0, as I should, I get -1.83691e-016

What am I missing here? I am in radians as I need to be.

Was it helpful?

Solution

First, M_PI is not a very portable macro and is usually good to about 15 decimal places, depending on the compiler you use - my guess is you're using Microsoft's C++ compiler.

Second, if you want a more accurate (and portable) version, use the Boost Math library: http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/non_templ.html

Third, as Kay has pointed out, pi in itself is an irrational number and therefore no amount of bits (or digits in base 10) would be enough to accurately represent it. Therefore, What you're actually calculating is not cos(3*pi/2) exactly, but "the cosine of 3/2 times the closest approximation of pi given the bits required", which will NOT be 3 *pi/2 and therefore won't be zero.

Finally, if you want custom precision for your mathematical constants, read this: http://www.boost.org/doc/libs/1_55_0/libs/math/doc/html/math_toolkit/tutorial/user_def.html

OTHER TIPS

The number M_PI is only an approximation of π. The cosine that you get back is also an approximation, and it's a pretty good one - it has fifteen correct digits after the decimal point.

Given the discrete nature of double values, the standard margin of error against which to test for numerical equality is numeric_limits<double>::epsilon():

#include <iostream>
#include <limits>
#include <cmath>

using namespace std;

int main()
{
  double x = cos(M_PI*3/2);
  cout << "x = << " << x << endl;
  cout << "numeric_limits<double>::epsilon() = "
       << numeric_limits<double>::epsilon() << endl;
  cout << "Is x sufficiently close to 0? "
       << (abs(x) < numeric_limits<double>::epsilon() ? "yes" : "no") << endl;
  return 0;
}

Output:

x = << -1.83697e-16
numeric_limits<double>::epsilon() = 2.22045e-16
Is x sufficiently close to 0? yes

As you can see, the absolute value of -1.83697e-16 is within the margin of error given by epsilon 2.22045e-16.

Pi is irrational, the computer cannot represent the number perfectly. The small error to the "correct" value of pi causes the error in the output. Being 1.83691 × 10-16 off is still pretty good.

If you want to learn more about the restrictions of actual system and the impact of little errors in the input, then refer to http://en.wikipedia.org/wiki/Numerical_stability.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top