本文介绍了atan2f使用m32标志给出不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一些代码从32位移植到64位,并确保答案相同.这样做时,我注意到atan2f在两者之间给出了不同的结果.

I'm porting some code from 32 bit to 64 bit, and ensuring the answers are the same. In doing so, I noticed that atan2f was giving different results between the two.

我创建了这个最小副本:

I created this min repro:

#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不会.

Note that atan2 gives the same result in both cases, but atan2f does not.

我尝试过的事情:

  1. 使用-ffloat-store构建32位版本

  1. Building the 32 bit version with -ffloat-store

使用-msse2 -mfpmath = sse

Building the 32 bit version with -msse2 -mfpmath=sse

使用-mfpmath = 387

Building the 64 bit version with -mfpmath=387

没有人为我改变结果.

(所有这些都是基于这样的假设,即它与32位和64位体系结构上的浮点运算发生方式有关.)

(All of these were based on the hypothesis that it has something to do with the way floating point operations happen on 32 bit vs 64 bit architectures.)

问题:

要让他们给出相同的结果,我有哪些选择?(有没有我可以使用的编译器标志?)而且,这里发生了什么?

What are my options for getting them to give the same result? (Is there a compiler flag I could use?) And also, what is happening here?

如果我有帮助,我正在i7机器上运行.

I'm running on an i7 machine, if that is helpful.

推荐答案

以十六进制表示法更容易看到.

This is easier to see in hex notation.

void testAtan2fIssue(float A, float B) {
    double d = atan2(A, B);
    printf("        atan2 : %.13a %.15f\n", d, d);
    float f = atan2f(A, B);
    printf("        atan2f: %.13a %.15f\n", f, f);
    printf("(float) atan2 : %.13a %.15f\n", (float) d, (float) d);

    float f2 = nextafterf(f, 0);
    printf("problem value : %.13a %.15f\n", f2, f2);
}

// _ added for clarity
        atan2 : 0x1.ea1f9_b9d85de4p+0 1.914544_797857041
        atan2f: 0x1.ea1f9_c0000000p+0 1.914544_820785522
(float) atan2 : 0x1.ea1f9_c0000000p+0 1.914544_820785522
problem value : 0x1.ea1f9_a0000000p+0 1.914544_701576233


double float 的转换预计是最佳的,但是 arctangent 函数可能是一些 ULP 在各种平台上均已关闭. 1.914544701576233 是下一个较小的 float 值,反映了稍差的反正切计算.

The conversion from double to float can be expected to be optimal, yet arctangent functions may be a few ULP off on various platforms. The 1.914544701576233 is the next smaller float value and reflects the slightly inferior arctangent calculation.

很少.代码可以从建立的 代码库中滚动您自己的 my_atan2().即便如此,在实现上也可能存在细微的差异. @stark

Few. Code could roll your own my_atan2() from an established code base. Yet even that may have subtle implementation differences. @stark

相反,请考虑使代码检查容忍微小的变化.

Instead, consider making code checking tolerant of the minute variations.

这篇关于atan2f使用m32标志给出不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 12:03