【问题标题】:Why does printf("%.2f", (double) 12.555) return 12.55?为什么 printf("%.2f", (double) 12.555) 返回 12.55?
【发布时间】:2019-01-28 01:50:17
【问题描述】:

我正在编写一个程序,我必须将双精度舍入到小数点后第二位。我注意到 printf("%.2f", (double) 12.555) 返回 12.55。但是,printf("%.2f", (float) 12.555) 返回 12.56。谁能解释为什么会这样?

【问题讨论】:

  • 用 6 位以上的数字打印出 float 和 double,看看结果如何。我假设不精确的值被正确舍入。 :)

标签: c++ floating-point double


【解决方案1】:

12.555 是一个不能用二进制浮点精确表示的数字。碰巧在您的系统上以双精度浮点表示的最接近 1.2555 的值略小于 1.2555,而以单精度浮点表示的最接近 1.2555 的值略大于 1.2555。

假设转换使用的舍入模式是四舍五入到最接近(与偶数相关),这是 IEEE 754 标准中的默认值,那么所描述的输出是预期的。

【讨论】:

    【解决方案2】:

    浮点数和双精度数使用IEEE 754 表示在内部存储。与您的问题相关的部分是,考虑到它们的表示限制,浮点数和双精度数都可以存储最接近十进制数的值。粗略地说,这些限制与将原始数字的小数部分转换为具有有限位数的二进制数有关。

    事实证明,最接近 12.555 的浮点数实际上是 12.55500030517578125,而最接近 12.555 的双精度浮点数是 12.554999999999999715782905696。请注意双精度如何提供更高的准确性,但误差是负数。

    在这一点上,现在可能很明显为什么 round 函数上升为 float 而下降为 double - 它们都四舍五入到最接近底层表示的 十进制 数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 2017-01-20
      • 2013-02-13
      • 2017-03-04
      • 2017-06-15
      • 2012-08-04
      相关资源
      最近更新 更多