I'm using the asin and acos functions from cmath library to find the angles from their corresponding sine and cosine values but it sometimes returns inaccurate values. For example the result of the code below is not zero:
cout << acos(-1) / 6 - asin(0.5) << endl;
So what can I do? I use acos(-1) as the value of Pi, then somewhere in my code I want to see for example how many asin(0.5) are there in Pi but current method doesn't work.
double
is very commonly encoded using base 2, such as with binary64. As a floating point number, it can be expected to be a Dyadic rational. The key is that a finite floating-point number is a rational number.
Mathematically, arccos(-1) is π. π is an irrational number. Even with many digits of precision, a double
cannot represent exactly π. Instead a nearby value for acos(-1)
is used called machine pi or perhaps M_PI
.
Mathematically, arcsin(0.5) is π/6. As above, asin(0.5)
is a nearby value to π/6.
Division by 3 introduces potential inexactness. About 2 of every double/3
results in an inexact, yet rounded, quotient.
What is curious about this is that acos(-1) / 3 - asin(0.5)
is about 1.57..., not 0.0.
I suspect OP was researching acos(-1) / 6 - asin(0.5)
.
Here subtraction of nearby values incurs catastrophic cancellation and a small, but non-zero difference, is a likely outcome.
So what can I do?
I want to see for example how many asin(0.5) are there in Pi
Tolerate marginal error in the calculation and employ the desired rounding.
double my_pi = acos(-1);
double target = asin(0.5);
long close_integer_quotient = lround(my_pi/target);