sin,cos,tan和舍入误差
我正在C / C ++中进行一些三角函数计算,并且遇到了舍入错误的问题。 例如,在我的Linux系统上:
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv[]) {
printf("%en", sin(M_PI));
return 0;
}
该程序提供以下输出:
1.224647e-16
当正确的答案当然是0。
使用trig函数时,我可以期待多少舍入误差? 我怎样才能最好地处理这个错误? 我熟悉最后一位的单位比较浮点数的技巧,来自Bruce Dawson的比较浮点数,但在这里似乎并不奏效,因为0和1.22e-16是相当多的ULP。
IEEE双存储52位尾数,“隐含前导1”形成53位数字。 因此,结果的最低位的错误占据了数字的1/2 ^ 53。 你的输出的顺序与1.0相同,所以在10 ^ 16中只有一个部分出现(因为53 * log(2)/ log(10)== 15.9)。
所以是的。 这是关于您可以预期的精度的限制。 我不确定你使用的ULP技术是什么,但是我怀疑你错误地应用了它。
sin(pi)的答案只有0 - 你是否包含了Pi的所有数字?
- 还有其他人注意到这里的讽刺/幽默感明显缺乏吗?
@Josh Kelley - 好的回答。
一般来说,你绝不应该比较任何涉及浮动或双打的操作的结果。
唯一的例外是分配。
float a = 10.0;
float b = 10.0;
然后a == b
否则,你总是必须编写一些函数,比如bool IsClose(float a,float b,float error),以便检查两个数字是否在对方的'错误'内。
记得也要检查标志/使用晶圆厂 - 你可能有-1.224647e-16