为什么sin(45)和cos(45)给出不同的结果?

时间:2015-07-20 04:49:26

标签: c++ angle pi sin cos

这是我不期待的。我知道这些数字并非100%准确,但我并不期望互补角度给出sincos的不同结果:

以下函数返回0.70710678118654746000000...

sin(45 * PI / 180.0);

这个follwing函数返回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)略有不同的数字,尽管它们应该相同。

此外,它不仅是sincos问题,而且还是sinsin问题:sin(1 * PI / 180.0)返回与sin(179 * PI / 180.0)不同的值,它们应该是相同的。

我尝试使用弧度而不是度数,并且存在完全相同的差异,我尝试使用小的PI值,一个巨大的PI值(大约100个小数以上),它们仍然不同,我尝试使用cmath代替math.h,我尝试使用M_PI而不是我自己定义的PI

差异总是相同的,大约是第16个小数。不要误解我的意思,我知道我永远不会得到这些数字的100%精确值,但至少我期望得到相同的"不精确的"互补角度的sincos的值。这一切到底是怎么回事?

我需要它们是相同的,因为我正在处理的程序(我被要求做的重力模拟器)使用具有double(我也试过float)变量的对象这基本上是角度(度数或弧度,我已尝试过两者)。这些是物体用来移动的方向,我也需要角度来计算物体之间的相互作用。

角度在程序的每次迭代中都会发生变化,并且在每次迭代中,角度都会根据前一次迭代角度的计算而变化,因此如果在任何点上存在任何最小错误的角度值,那么该错误在每次迭代中越来越多地被放大。

该程序运行数千甚至数百万次迭代,因此价值的误差非常大!说清楚,行星最终摆脱了平衡,一切都变成了灾难,我真的很生气:(

P.S。我在Windows 7上,32位。

2 个答案:

答案 0 :(得分:3)

  

我知道我永远不会得到这些数字的100%精确值,但AT   至少我期待获得与罪和cos相同的“不确定”价值   互补角度。

为什么呢?计算方式不同,因此会出现(并累积)不同的浮点错误。你看到的不是错误; FP算法不能通过数学定律预测。

顺便说一句,提供例如。 PI的30或100位数不会有任何不同 如果您的类型首先不能容纳30位数字。

答案 1 :(得分:2)

  

无论计算方式如何,都应该返回相同的值

您的期望不正确。在IEEE-754中,只需要对基本运算符(+-*/)和sqrt进行正确舍入。像sincosexp这样的Trancendental函数不是必需的,因为它非常复杂

  

没有标准要求忠实地舍入超越功能。 IEEE-754(2008)建议,但不要求这些功能正确舍入。

现在,如果你看看你的价值观

                                      ↓
0.70710678118654746 = 0x1.6a09e667f3bccp-1
0.70710678118654757 = 0x1.6a09e667f3bcdp-1
                                      ↑

因此它们彼此相距1 p并且精确到双精度

  不要误会我的意思,我知道我永远不会得到这些数字的100%精确值,但至少我期待得到相同的"不准确" sin的值和互补角的cos

不仅要计算sincos的单一算法。对于某些输入,每个输入都是正确的,但对于其他输入则不正确。它们也有不同的内存和时间要求,因此有些可能非常快,错误率更高,有些则需要更多的时间和内存,但它们可以实现更高的精度。

编译器实现可能会对这些函数使用不同的算法,因此如果您需要一致的结果,请在跨平台使用一个精心设计的库。例如,无论平台如何,GCC都使用MPFR来实现正确的舍入结果

  

GCC中端已与MPFR库集成。这允许GCC在编译时对内置数学函数的调用进行求值和替换,这些函数具有常数参数及其数学上等效的结果。在使用MPFR时,无论数学库实现或主机平台的浮点精度如何,GCC都可以生成正确的结果。这也允许GCC生成相同的结果,无论是否将本机编译或交叉编译配置编译到特定目标

     

https://gcc.gnu.org/gcc-4.3/changes.html#mpfropts

How does C compute sin() and other math functions?