【问题标题】:sin(<minus zero>) does not return the expected result on Visual Studio 2013 64bitsin(<minus zero>) 在 Visual Studio 2013 64 位上不返回预期结果
【发布时间】:2015-08-04 05:57:31
【问题描述】:

在我开发的工程应用程序中,我偶然发现了 32 位和 64 位之间 sin(-0) 的结果存在差异。由于计算的性质,这会传播到一些相位差。

我们正在使用 MSVC 2013 在 Windows 上进行开发。

显然,浮点标准指定 sin(-0) 返回参数不变 - 至少根据 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) 也返回 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;
}

【问题讨论】:

  • 使用 VS2013 Win8 x64 对我来说工作正常。但无法在 Win7 上测试。
  • 在 vs2015 上也能正常工作
  • 我确认我在 VS 2013、Update 4、Windows 7 上看到了同样的问题。Win32 和 x64 配置的不同输出。
  • IIRC,x64 默认为 SSE,x86 构建默认为 x87 数学。所以这可能不是 32 与 64 位的问题,而是 x87 与 SSE 的问题。
  • @MSalters 默认情况下确实如此。但是,我还切换了所有可用的 /arch Visual Studio 选项,结果在 32 位(即正确)和 64 位(即:不正确)之间是一致的。因此,要么该选项没有影响,要么错误出在 MS 例程中的实现方面。

标签: c++ visual-c++ visual-studio-2013 ieee-754


【解决方案1】:

最后我求助于穷人的解决方案。我专门使用 std::signbit 检查 -0 和接近于零,并考虑 sin(-0) = -0。 慢?也许吧,但对我们的需求是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多