Reputation: 325
I have an equation:
double center = self.Altitude * tan(Pitch);
Where Altitude = 130
Pitch = 90 degrees and for this equation I converted it to 1.570796 radians
Using a calculator I got the answer: 397802904
The program got: -362461013356.731689
Any ideas why?
Thank you!
Upvotes: 0
Views: 780
Reputation: 153338
Your variant results are due to your conversion from degrees to radians is not executed properly to get the expected tan()
result. It is not a "tan(PI/2) is undefined" issue. It is a degrees to radians and tangent(x near 90 degrees) issue.
When you converted 90 degrees to radians, you did not get 1.570796 as you report. Instead, when you converted 90 degrees to radians, the result was near 1.570796. Very likely you thought you converted to 1.570796 because that is what appeared when you saw a decimal representation of the conversion. That decimal conversion is a rounded representation of internal floating point representation. More likely the value you had was more like 1.570796324... for the tangent of that number is about 397802904.
When you attempt to convert degrees to radians, you use something like degrees*2*PI/360
. The problem is that one is unable to represent PI exactly and thus the conversion result is approximate. tan(x)
is extraordinarily sensitive to slight variation about PI/2 and since you likely used slightly different values of PI and/or your functions are every so slightly different, you got massively different answers.
Regardless of your precision, your can not represent Pi exactly in floating point notation and thus tan(MACHINE_APPROXIMATE_PI/2)
will not equal 0.
To get better answers using degrees, you must do your argument range reductions in degrees before converting to radians.
// Only for 0 <= angle <= 90
double tan_degree(double angle) {
if (angle > 45) {
if (angle == 90) {
return INF;
}
angle = 90 - angle;
return 1/tan(angle*2*PI/360);
}
else {
return tan(angle*2*PI/360);
}
}
To determine the tan_degree() for other angles, similar angle reduction is needed.
A similar range reduction is needed for sin_degree() and cos_degree().
Upvotes: 0
Reputation: 881103
The tangent of 90 degrees is not defined. That makes sense if you think of it as the gradient of the line intersecting a circle. At 90 degrees, the line is vertical, hence has an undefined gradient.
You probably should have gotten NaN
as the result from your tan()
call, unless in your conversion it didn't go to exactly PI/2 radians. You'd be better off using the constants supplied for this purpose:
double rads = (double)degs * M_PI / 180.0; // in C, not sure about ObjC.
so as to minimise the potential for error.
More than likely, because you're dealing with really large numbers, any minor variations in precision between your calculator and computer will have a proportionate effect on the answer.
The difference in gradients between 1 and 2 degrees is fairly small (0.017 -> 0.035) since the lines are both very close to horizontal. The difference between 88 and 89 degrees is much larger (29 -> 57). The difference between 89 and 89.999 is truly massive (57 to 57,000).
Upvotes: 3