【发布时间】:2015-10-09 03:13:25
【问题描述】:
这是我没想到的。我知道这些数字不是 100% 准确的,但我没想到互补角度会给出 sin 和 cos 的不同结果:
以下函数返回0.70710678118654746000000...
sin(45 * PI / 180.0);
虽然下面的函数返回0.70710678118654757000000...
cos(45 * PI / 180.0);
所以,它是:
0.707106781186547**46**000000... vs
0.707106781186547**57**000000...
不仅如此……sin(1 * PI / 180.0) 还返回与cos(89 * PI / 180.0) 略有不同的数字,尽管它们应该相同。
此外,这不仅是 sin 与 cos 的问题,也是 sin 与 sin 的问题:sin(1 * PI / 180.0) 返回的值与 sin(179 * PI / 180.0) 不同,它们应该是相同的。
我尝试使用弧度而不是度数,但差异完全相同,我尝试使用较小的 PI 值,较大的 PI 值(大约 100 位小数或更多),但它们仍然不同,我尝试使用cmath而不是math.h,我尝试使用M_PI而不是我自己定义的PI。
差异始终相同,大约在小数点后 16 位左右。不要误会我的意思,我知道我永远不会得到这些数字的 100% 精确值,但至少我期望得到与互补角 sin 和 cos 相同的“不精确”值。这到底是怎么回事?
我需要它们相同,因为我正在处理的程序(我被要求做的重力模拟器)使用具有double(我也尝试过float)变量的对象,这些变量基本上是角度(度或弧度,我都试过了)。这些是物体用来移动的方向,我也需要角度来计算物体之间的相互作用。
在程序的每次迭代中角度都会发生变化,并且在每次迭代中,角度都会根据上一次迭代角度的计算而变化,因此,如果在任何点有任何最小错误的角度值,那么该错误就会被放大更多并且每次迭代都有更多。
程序运行了数千甚至数百万次迭代,因此值的错误变得非常大!说清楚,行星最终会失去平衡,一切都变成了一场灾难,我真的很生气:(
附:我在 Windows 7 上,32 位。
【问题讨论】:
-
双精度只有大约 16 位小数。
-
好吧,我知道我永远不会得到 sin(45) 的完美值,这样的值不存在,完美的圆形 PI 值也不存在,但我在最不希望互补角以同样的方式出错:/
-
您可能想要寻找(或实现)一个符号计算库。当然,您会牺牲性能来换取精度。
标签: c++ floating-point trigonometry angle pi