【发布时间】:2014-10-21 23:09:35
【问题描述】:
在 OSX 10.10 和 ubuntu 14.04 上分别编译和运行。
#include<float.h>
#include<math.h>
#include<stdio.h>
void testAtan() {
float temp1 = 62981764.0000000000000000f;
float temp2 = (2.14859168E8f * atanf(temp1));
printf("temp2: %.16f\n", temp2);
}
int main() {
printf("FLT_EVAL_METHOD=%d\n", FLT_EVAL_METHOD);
testAtan();
return 0;
}
在 OS X 上,它会打印
FLT_EVAL_METHOD=0
temp2: 337499968.0000000000000000
在 ubuntu 上,它会打印
FLT_EVAL_METHOD=0
temp2: 337500000.0000000000000000
有什么想法可以证明这一点以及使结果一致的方法吗?
【问题讨论】:
-
一个 32 位 IEEE754 浮点数只有大约 7 个十进制数字的精度,所以两个结果是一致的。这就是“精确”的含义。
-
原因的提示可以在 Apple 的
atanf实现的 cmets 中找到:opensource.apple.com/source/Libm/Libm-315/Source/Intel/atanf.s 其他人应该能够从那里得到它。 -
@KerrekSB:如果这就是“精度”的含义,那么这不是“32 位 IEEE754 浮点”的含义。他显示的两个结果相差一个 ulp。
-
@KerrekSB 此评论反映了格式的精度 和操作的准确度 之间的混淆。 binary32 IEEE 754 格式具有(相当于)7 个十进制数字的精度,但是在两个不同的 IEEE 754 编译平台上应用于相同参数的两个基本操作的结果可以预期等于 2^-1000000000000,因为可以预期它们是相同的。仅仅因为精度约为 7 位十进制数字并不意味着两次计算应该有差异。它们可以相差更多,也可以相差更少(通过相同)。
-
@PascalCuoq:是的,好点,歧义确实来自于库函数缺乏准确性限制(有时甚至是基本操作;C 不强制 IEEE754 操作语义,即使它使用标准数据类型表示)。
标签: c gcc floating-point clang