sin(<minus zero>) 没有 return Visual Studio 2013 64 位的预期结果
sin(<minus zero>) does not return the expected result on Visual Studio 2013 64bit
在我开发的工程应用程序中,我偶然发现了 32 位和 64 位之间 sin(-0) 结果的差异。由于计算的性质,这会传播到一些相位差。
我们正在使用 MSVC 2013 Windows 进行开发。
显然,浮点标准指定 sin(-0) return 参数不变 - 至少根据 cppreference/sin。
我做了一些调查,这些是我得到的一些其他结果:
// Visual Studio 2013 32 bit on Win7 - default arguments
std::sin( -0 ) = -0
std::sin( 0 ) = 0
// Visual Studio 2013 64 bit on Win7 - default arguments
std::sin( -0 ) = 0 // the faulty one
std::sin( 0 ) = 0
// g++ (GCC) 5.1.0 : g++ -std=c++11 -O2 -Wall -pedantic -mfpmath=387 -m64 main.cpp && ./a.out
std::sin( -0 ) = -0
std::sin( 0 ) = 0
// g++ (GCC) 5.1.0 : g++ -std=c++11 -O2 -Wall -pedantic -mfpmath=sse -m64 main.cpp && ./a.out
std::sin( -0 ) = -0
std::sin( 0 ) = 0
我还知道英特尔数学库 (libm*.dll) 也 return sin(-0)=-0。
查看反汇编,std::sin 的执行直接进入 msvcr120d.dll。
题目:
- 这是微软在 64 位上的 sin 例程实现的错误吗?
- 我是否应该使用一些我不知道的特定编译器参数?
用于上述输出的代码:
#include <cmath>
#include <iostream>
void printSin( const double dfPh )
{
const auto dfSinPh = std::sin( dfPh );
std::cout.precision( 16 );
std::cout << "std::sin( " << dfPh << " ) = " << dfSinPh << std::endl;
}
int main()
{
printSin( -0.00000000000000000000 );
printSin( +0.00000000000000000000 );
return 0;
}
最后我用了穷人的办法。我专门使用 std::signbit 检查 -0 并接近零,并考虑 sin(-0) = -0。
减缓?也许吧,但符合我们的需要。
在我开发的工程应用程序中,我偶然发现了 32 位和 64 位之间 sin(-0) 结果的差异。由于计算的性质,这会传播到一些相位差。
我们正在使用 MSVC 2013 Windows 进行开发。
显然,浮点标准指定 sin(-0) return 参数不变 - 至少根据 cppreference/sin。
我做了一些调查,这些是我得到的一些其他结果:
// Visual Studio 2013 32 bit on Win7 - default arguments
std::sin( -0 ) = -0
std::sin( 0 ) = 0
// Visual Studio 2013 64 bit on Win7 - default arguments
std::sin( -0 ) = 0 // the faulty one
std::sin( 0 ) = 0
// g++ (GCC) 5.1.0 : g++ -std=c++11 -O2 -Wall -pedantic -mfpmath=387 -m64 main.cpp && ./a.out
std::sin( -0 ) = -0
std::sin( 0 ) = 0
// g++ (GCC) 5.1.0 : g++ -std=c++11 -O2 -Wall -pedantic -mfpmath=sse -m64 main.cpp && ./a.out
std::sin( -0 ) = -0
std::sin( 0 ) = 0
我还知道英特尔数学库 (libm*.dll) 也 return sin(-0)=-0。
查看反汇编,std::sin 的执行直接进入 msvcr120d.dll。
题目:
- 这是微软在 64 位上的 sin 例程实现的错误吗?
- 我是否应该使用一些我不知道的特定编译器参数?
用于上述输出的代码:
#include <cmath>
#include <iostream>
void printSin( const double dfPh )
{
const auto dfSinPh = std::sin( dfPh );
std::cout.precision( 16 );
std::cout << "std::sin( " << dfPh << " ) = " << dfSinPh << std::endl;
}
int main()
{
printSin( -0.00000000000000000000 );
printSin( +0.00000000000000000000 );
return 0;
}
最后我用了穷人的办法。我专门使用 std::signbit 检查 -0 并接近零,并考虑 sin(-0) = -0。 减缓?也许吧,但符合我们的需要。