C++与sprintf绑定的舍入行为一致性

kmc*_*mee 7 c++ printf gcc visual-studio

我有一个在Windows/Linux上运行的C++程序.在Windows上,程序是使用Visual Studio 2012和Linux编译的,它是使用GCC编译的.使用sprintf将双精度转换为字符串时,Visual Studio使用与GCC编译器不同的舍​​入方法进行绑定 - 即以5结尾的小数.

Visual Studio编译器似乎执行了从零开始的一半,而GCC 甚至绕过了名为银行家的四舍五入.

Round even是理想的行为.

是否可以在visual studio/windows中更改用于sprintf格式字符串的舍入行为?因为我需要使舍入在两者之间保持一致.

这是一个小样本C++程序,它说明了上述行为:

int main()
{   
   char buffer[100];

   double x;
   for (x = -0.5; x <= 10.5; x += 1.0)
   {
      sprintf(buffer,"%4g %.0f\n", x, x);

      std::cout << buffer;
   }  

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

Windows输出.数字从零开始舍入:

视窗

使用xCode编译的OSX输出.使用圆形甚至朝向偶数舍入数字:

OSX

OSX输出:

Sha*_*our 3

这是 C11 标准草案中的实现定义行为7.21.6.1fprintf 函数涵盖了sprintf格式说明符和 C++,因为 C++ 标准依赖于 stdio 函数的 C 标准,它对于格式f说明符表示:

\n\n
\n

该值将四舍五入为适当的位数。

\n
\n\n

缺陷报告 211也涵盖了这一点,其中添加了以下内容:

\n\n
\n

浮点运算(+、-、*、/)以及返回浮点结果的库函数的准确性是实现定义的,浮点内部表示和字符串表示之间的转换的准确性也是如此。由 、 和 中的库例程执行。实现可能会指出准确性未知。

\n
\n\n

打印浮点数的不一致舍入一文详细介绍了这种不一致,并提到:

\n\n
\n

glibc printf() 已更新,以考虑当前的 IEEE 舍入模式。这是在 2.17 版本中完成的;我刚刚在2.18版本上测试过。当然,这样做时,舍入到最近的/舍入到远离零的一半仍然不是一个选项,因此这并不能帮助您使其输出与其他平台保持一致。

\n
\n\n

但正如所说,这无助于跨平台一致性。

\n