cosf(M_PI_2)没有返回零 [英] cosf(M_PI_2) not returning zero

查看:181
本文介绍了cosf(M_PI_2)没有返回零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这突然开始今日早盘。

原线路是这一

float angle = (x+90)*(M_PI/180.0);
float xx = cosf(angle);
float yy = sinf(angle);

把一个断点,并徘徊在光标后..我得到YY的正确答案为1,但XX不为零。

After putting a breakpoint and hovering cursor.. I get the correct answer for yy as 1. but xx is NOT zero.

我试着用 cosf(M_PI_2); 仍然没有运气..这是工作的罚款,直到昨天。我并没有改变任何编译器设置等。

I tried with cosf(M_PI_2); still no luck.. it was working fine till yesterday.. I did not change any compiler setting etc..

我用X code最新版本为今天的日期

I am using Xcode latest version as of todays date

推荐答案

相反的是其他人所说,这是不会的的x87协处理器的问题。 X code对英特尔使用SSE浮点运算默认情况下(除了长双算术)。

Contrary to what others have said, this is not an x87 co-processor issue. XCode uses SSE for floating-point computation on Intel by default (except for long double arithmetic).

问题是:当你写 cosf(M_PI_2),你实际上是告诉X code编译器(GCC或LLVM-GCC或铛)做到以下几点:

The "problem" is: when you write cosf(M_PI_2), you are actually telling the XCode compiler (gcc or llvm-gcc or clang) to do the following:


  1. 查找 M_PI_2 的扩张<&math.h中GT; 。每POSIX标准,它是一个双precision文字将转换为π/ 2的正确舍入值。

  2. 圆形转换的双重precision价值为单precision。

  3. 调用数学库函数 cosf 上的单个precision值。

  1. Look up the expansion of M_PI_2 in <math.h>. Per the POSIX standard, it is a double precision literal that converts to the correctly rounded value of π/2.
  2. Round the converted double precision value to single precision.
  3. Call the math library function cosf on the single precision value.

需要注意的是,在此过程中,你是不是在操作的实际的π/ 2的值。您是四舍五入到一个重新presentable浮点数该值,而不是操作。虽然COS(π/ 2)的究竟的零,你是不是告诉编译器做计算。你是不是告诉编译器做COS(π/ 2 +微小),其中微小的舍入值(浮点)M_PI_2 和(unre $ P $的区别psentable)π/ 2的精确值。如果 COS 计算没有错误可言,COS的结果(π/ 2 +微小)约为-tiny。如果它返回零,将是一个错误。

Note that, throughout this process, you are not operating on the actual value of π/2. You are instead operating on that value rounded to a representable floating-point number. While cos(π/2) is exactly zero, you are not telling the compiler to do that computation. You are instead telling the compiler to do cos(π/2 + tiny), where tiny is the difference between the rounded value (float)M_PI_2 and the (unrepresentable) exact value of π/2. If cos is computed with no error at all, the result of cos(π/2 + tiny) is approximately -tiny. If it returned zero, that would be an error.

编辑:在英特尔MAC一步一步扩展计算与当前的X code编译器:

edit: a step-by-step expansion of the computation on an Intel mac with the current XCode compiler:

M_PI_2 定义为

1.57079632679489661923132169163975144

但实际上并不是一个重新presentable双precision号。当编译器将其转换为它变成完全是一个双precision值

but that's not actually a representable double precision number. When the compiler converts it to a double precision value it becomes exactly

1.5707963267948965579989817342720925807952880859375

这是最接近双precision号码到π/ 2,但它从π/ 2的实际的数学值由大约6.12 * 10 ^不同。( - 17)

This is the closest double-precision number to π/2, but it differs from the actual mathematical value of π/2 by about 6.12*10^(-17).

步骤(2)舍这个数字单幅precision,从而改变了值精确

Step (2) rounds this number to single-precision, which changes the value to exactly

1.57079637050628662109375

其大约π/ 2 + 4.37 * 10 ^( - 8)。当我们计算 cosf 这个数字的话,我们得到:

Which is approximately π/2 + 4.37*10^(-8). When we compute cosf of this number then, we get:

-0.00000004371138828673792886547744274139404296875

这是的非常的在这一点上计算余弦近精确值:

which is very nearly the exact value of cosine evaluated at that point:

-0.00000004371139000186241438857289400265215231661...

在事实上,它是的正确舍入的结果的;没有该计算可能已经返回,这将是更精确的值。这里唯一的错误是,你要求编译器执行的计算是从您的计算不同的思维的你问它做。

In fact, it is the correctly rounded result; there is no value that the computation could have returned that would be more accurate. The only error here is that the computation that you asked the compiler to perform is different from the computation that you thought you were asking it to do.

这篇关于cosf(M_PI_2)没有返回零的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆