【问题标题】:C++ Rounding behavior consistency for ties with sprintf与 sprintf 关联的 C++ 舍入行为一致性
【发布时间】:2015-09-17 12:07:48
【问题描述】:

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

Visual Studio 编译器似乎执行 round half away from zero,而 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;
}

Windows 输出。数字从零开始四舍五入:

使用 xCode 编译的 OSX 输出。数字使用 round even 向偶数四舍五入:

OSX 输出:

【问题讨论】:

标签: c++ visual-studio gcc printf


【解决方案1】:

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

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

defect report 211 也涵盖了这一点,其中添加了以下内容:

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

文章Inconsistent Rounding of Printed Floating-Point Numbers 详细介绍了这种不一致并提到:

glibc printf() 已更新以考虑当前的 IEEE 舍入模式。这是在 2.17 版中完成的;我刚刚在 2.18 版本上对其进行了测试。当然,以这种方式进行时,从零开始舍入到最近/半舍入仍然不是一种选择,因此这并不能帮助您使其输出与其他平台保持一致。

但如前所述,这对跨平台一致性没有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多