Sin和Cos函数返回不正确的结果

时间:2012-12-12 18:16:48

标签: objective-c math

  

可能重复:
  getting value of sine 180 as 1.22465e-16

我正在计算圆周上的一个点。我有半径和圆的中心点。 在这里你会说,大不了,有一个直接的公式相同。 是的,角度是rad

x = x + r*sin(angle)
y = y + r*cos(angle)

好的,现在这里的问题是即使我以弧度传递角度。然而,我没有得到下面提到的角度的正确答案

for 90 degree (rads = 1.5708) i get y axis = -4.3774e-08
for 180 degree (rads = 3.14159) i get x axis = -8.74228e-08
for 270 degree (rads = 4.71239) i get y axis = 1.19249e-08
for 360 degree (rads = 6.28319) i get x asix = 1.74846e-07

我用

将Degree转换为Radians
return degrees * M_PI / 180;

我不确定为什么会这样。 一定有严重的错误。

以下是用于转换的代码

float angle = DegreesToRadians(90);

float x = sin(angle);
float y = cos(angle);

任何人都可以帮我吗?

3 个答案:

答案 0 :(得分:8)

M_PI在“math.h”中定义为

#define M_PI        3.14159265358979323846264338327950288

大约(无理)数字Pi。因此

cos(M_PI/2), sin(M_PI), cos(3*M_PI/2), sin(2*M_PI)

大约零。 Pi无法完全表示为floatdouble

从您的输出中我假设您使用了float。 由于float的有效位数约为7,而sin()cos()的斜率(一阶导数)为+/- 1,我会说结果和你期望的一样好。使用double可以获得更好的结果,但不会完全为零。

因此没有严重错误,你只是不能指望浮点计算的结果是准确的。

答案 1 :(得分:1)

duplicate问题添加评论......

一种替代方法是使用梯度或度数而不是弧度,这样全圆的倍数以及每个象限的倍数都是整数,而那些参数的正弦和余弦也可以是完全代表。

另外一个人必须惊叹数学库的某些实现处理pi的倍数:因为浮点数或双精度数中的pi的表示与真实值相差一些小的 delta ,那么由此得出N *(pi + -delta)与真实值相差N * delta。因此,在写得很好的库中,sin((pi / 2)+(2 * pi)* n)随n增加;对于写得不好的库,参数以2 * pi的模数近似进行评估,为每个 n 提供完全相同的偏移量。

答案 2 :(得分:0)

通常,在处理浮点数时,不建议将结果(等于)与任何特定数字进行比较,可能是0,1或甚至是pi或e。 -8.74228e-08足够接近在实际所有可计算的情况下被视为0。 (如果没有,那么无论如何你都有浮动/双重的重要性问题)

如果您需要在程序代码中比较它们,您应该减去这些值并将结果与​​<或者>还有一些非常小的数字。例如

if (sin(something*pi) < 0.0001f) ...

而不是

if (sin(something*pi) == 0) ...