C++ gcc和sin/cos/超越函数与Windows中的精度类似

C++ gcc和sin/cos/超越函数与Windows中的精度类似,c++,gcc,floating-point,C++,Gcc,Floating Point,我希望在gcc/Linux移植版本的Windows软件中实现完全相同的浮点结果。因此,我希望所有的双精度运算都是64位精度的。这可以使用-mpc64或-msse2或-fstore浮动(都有副作用)来实现。然而,有一件事我无法解决,那就是像sin/asin这样的超越函数。文档说,他们内部期望(并使用我猜想的)长双精度,无论我做什么,他们产生的结果都不同于Windows对应的结果 这些函数如何能够使用64位浮点精度计算结果 更新:我错了,是printf(“%.17f”)错误地舍入了正确的双精度结果,

我希望在gcc/Linux移植版本的Windows软件中实现完全相同的浮点结果。因此,我希望所有的双精度运算都是64位精度的。这可以使用-mpc64或-msse2或-fstore浮动(都有副作用)来实现。然而,有一件事我无法解决,那就是像sin/asin这样的超越函数。文档说,他们内部期望(并使用我猜想的)长双精度,无论我做什么,他们产生的结果都不同于Windows对应的结果

这些函数如何能够使用64位浮点精度计算结果


更新:我错了,是printf(“%.17f”)错误地舍入了正确的双精度结果,gdb中的“print x”表示数字本身是正确的。我想我需要一个不同的问题。。。也许是关于如何使printf不将double内部视为扩展。也许使用stringstream会得到预期的结果。。。是的。不同的LibM库对基本函数使用不同的算法,因此必须在Windows和Linux上使用相同的库才能获得完全相同的结果。我建议编译
FDLibM
并将其与您的软件静态链接。

当我使用stringstream时,我发现是printf(“%.17f”)使用了不正确的精度来打印结果(可能是内部扩展的)。对于超越函数问题,一个很好的解决方案是使用GNU MPFR库。但请注意,Microsoft编译器不支持扩展精度浮点。对于Microsoft编译器,double和long double都是53位精度。对于gcc,长双精度是64位精度。要在Windows/linux上获得匹配结果,必须避免使用long-double或Microsoft编译器。对于许多Windows项目,gcc的Windows端口(mingw)运行良好。这允许Windows项目使用64位精度长双精度。mingw-long-double支持的一个问题是,mingw使用Microsoft库进行printf等调用。因此,打印长双精度打印无法正常工作。解决这个问题的方法是使用mpfr_printf。

您是否使用Microsoft的编译器为Windows编译了上述软件?浮点的编译选项是什么?这里有几个选项,请参见
精确
快速
严格
等等。此外,您能否查看两个版本的反汇编,以了解它们的具体差异?您能否确保这些函数不是由标准库的实现者使用查找表实现的?它是以精确的方式编译的,文档中说:“中间表达式是以默认的53位精度计算的”。至于查找表等,我不知道。但gcc的docs表示,“请注意,一些数学库假设默认情况下启用了扩展精度(80位)浮点运算;当使用此选项[mpc64]时,此类库中的例程可能会遭受严重的精度损失,通常是通过所谓的“灾难性取消”用于将精度设置为小于扩展精度。”(c)gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.htmln早在一年前,您就提出了下面链接的问题,为了总结答案,不会有Linux修复此问题,因为Windows是错误的,Linux是正确的。你现在说的话听起来和你当时说的非常非常相似。是什么让你觉得这又不是同一个“问题”?这是一个完全不同的问题。其中一个原因是Windows忽略了精度>17,而gcc则没有。在将gcc限制为.17之后,我得到了相同的结果。这一个是相同的。17精度赢和gcc产生不同的结果。实际上,即使在gcc上使用setprecision(17)和printf(“%.17g”)的stringstream也会产生不同的结果。