【发布时间】:2017-06-21 10:04:46
【问题描述】:
我正在将一些代码从 32 位移植到 64 位,并确保答案相同。这样做时,我注意到 atan2f 在两者之间给出了不同的结果。
我创建了这个最小再现:
#include <stdio.h>
#include <math.h>
void testAtan2fIssue(float A, float B)
{
float atan2fResult = atan2f(A, B);
printf("atan2f: %.15f\n", atan2fResult);
float atan2Result = atan2(A, B);
printf("atan2: %.15f\n", atan2Result);
}
int main()
{
float A = 16.323556900024414;
float B = -5.843180656433105;
testAtan2fIssue(A, B);
}
当构建时:
gcc compilerTest.c -m32 -o 32bit.out -lm
它给出:
atan2f: 1.914544820785522
atan2: 1.914544820785522
当构建时:
gcc compilerTest.c -o 64bit.out -lm
它给出:
atan2f: 1.914544701576233
atan2: 1.914544820785522
请注意,atan2 在两种情况下都给出相同的结果,但 atan2f 不会。
我尝试过的事情:
使用 -ffloat-store 构建 32 位版本
使用 -msse2 -mfpmath=sse 构建 32 位版本
使用 -mfpmath=387 构建 64 位版本
没有人改变我的结果。
(所有这些都是基于它与浮点运算在 32 位和 64 位架构上发生的方式有关的假设。)
问题:
我有哪些选择可以让他们给出相同的结果? (有没有我可以使用的编译器标志?)还有,这里发生了什么?
我在 i7 机器上运行,如果有帮助的话。
【问题讨论】:
-
使用
"atan2f: %.15f\n"打印可能不够精确。使用"%.16e\n"或更好的"%a\n"进行调查。 -
为什么您希望两个不同的库提供完全相同的结果,以及在两个平台上哪个大小具有
float?不同之处并不是人们会担心的。 -
请注意,
1.914544701576233和1.914544820785522在 ULP 中相差 2 位 -
几乎没有情况应该依赖两个不同的浮点计算来得到相同的结果。
-
32 位浮点数只能精确到 6 或 7 位有效数字:不是 15。64 位系统上的 sizeof(float) 是 4 还是 8?
标签: c floating-point 32bit-64bit