我有一个等式:
double center = self.Altitude * tan(Pitch);
其中海拔 = 130
Pitch = 90 度,对于这个等式,我将其转换为 1.570796 弧度
使用计算器我得到了答案:397802904
程序得到:-362461013356.731689
任何想法为什么?
谢谢!
我有一个等式:
double center = self.Altitude * tan(Pitch);
其中海拔 = 130
Pitch = 90 度,对于这个等式,我将其转换为 1.570796 弧度
使用计算器我得到了答案:397802904
程序得到:-362461013356.731689
任何想法为什么?
谢谢!
未定义 90 度的切线。如果您将其视为与圆相交的线的渐变,这是有道理的。在 90 度时,线是垂直的,因此具有未定义的渐变。
您可能应该从您的通话中得到NaN
结果tan()
,除非在您的转换中它没有完全达到PI/2 弧度。您最好使用为此目的提供的常量:
double rads = (double)degs * M_PI / 180.0; // in C, not sure about ObjC.
以尽量减少出错的可能性。
很有可能,因为您处理的是非常大的数字,所以计算器和计算机之间精度的任何微小变化都会对答案产生成比例的影响。
1 度和 2 度之间的梯度差异非常小(0.017 -> 0.035),因为两条线都非常接近水平线。88 度和 89 度之间的差异要大得多(29 -> 57)。89 和 89.999 之间的差异确实很大(57 到 57,000)。
您的变体结果是由于您从度数到弧度的转换未正确执行以获得预期tan()
结果。这不是“tan(PI/2)未定义”问题。这是弧度和切线(x接近90 度)的度数问题。
当您将 90 度转换为弧度时,您在报告时没有得到 1.570796。相反,当您将 90 度转换为弧度时,结果接近1.570796。您很可能认为您已转换为 1.570796,因为当您看到转换的十进制表示时就会出现这种情况。该十进制转换是内部浮点表示的四舍五入表示。您拥有的值更有可能更像 1.570796324... 因为该数字的正切约为 397802904。
当您尝试将度数转换为弧度时,您使用类似degrees*2*PI/360
. 问题是无法准确表示 PI ,因此转换结果是近似的。 对 PI/2的微小变化非常tan(x)
敏感,并且由于您可能使用了略有不同的 PI 值和/或您的函数都略有不同,因此您得到的答案大不相同。
无论您的精度如何,您都不能准确地用浮点表示法表示 Pi,因此tan(MACHINE_APPROXIMATE_PI/2)
不会等于 0。
要使用度数获得更好的答案,您必须在转换为弧度之前以度数减少参数范围。
// 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);
}
}
要确定其他角度的 tan_degree(),需要类似的角度缩减。
sin_degree() 和 cos_degree() 需要类似的范围缩减。