【问题标题】:PHP integer rounding problemsPHP整数舍入问题
【发布时间】:2011-05-13 06:37:51
【问题描述】:

echo (int) ( (0.1+0.7) * 10 );

为什么上面的输出是 7?我了解 PHP 如何向 0 舍入,但 (0.1+0.7) * 10 不是评估为浮点数然后转换为整数吗?

谢谢!

【问题讨论】:

  • 我认为这发生在任何语言中,这是因为浮点数在内部处理的方式

标签: php floating-point integer


【解决方案1】:

我没有安装php,但是在python中:

$ python
>>> 0.1+0.7
0.79999999999999993
>>> 

并非所有以 10 为底的数字都可以在以 2 为底的系统中精确表示。查看维基百科文章:

部分二进制分数。特别是这一行:

Fraction    Decimal     Binary  Fractional Approx.
1/10    0.1     0.000110011...  1/16+1/32+1/256...

1/10 不能以 2 为底的有限方式表示。因此,0.1 + 0.7 不能以 2 为底精确计算。

永远不要假设浮点计算是精确的,它迟早会咬你。

【讨论】:

    【解决方案2】:

    当小数在内部转换为等效的二进制时,精度会有所下降。计算值将类似于 7.9+,而不是预期的 8。

    如果您需要高精度,请使用GMP 系列函数或bcmath 库。

    【讨论】:

      【解决方案3】:

      参见手册:

      http://php.net/manual/en/language.types.float.php

      简单的小数是典型的 不能像 0.1 或 0.7 这样的分数 转换成它们的内部二进制文件 同行没有小的损失 精确。这可能会导致混乱 结果:例如, floor((0.1+0.7)*10) 通常会 返回 7 而不是预期的 8, 因为内部表示将 大概是 7.9。

      【讨论】:

        【解决方案4】:

        1/10 不能用有限数量的二进制数字表示,就像 1/3 不能用有限数量的 base-10 数字表示一样。因此,您实际上是在将 0.09999999999999... 和 0.69999999999999... 相加 - 总和是几乎 8,但不完全。

        【讨论】:

          【解决方案5】:

          其他答案解释了为什么会发生这种情况。这应该可以得到你想要的:

          echo (int) round( (0.1+0.7) * 10 );
          

          在将浮点数转换为 int 之前,只需 四舍五入

          【讨论】:

          • 另外,它建议您实际上不要使用浮点数进行货币计算,因为这种精度损失
          猜你喜欢
          • 1970-01-01
          • 2020-09-17
          • 2011-12-14
          • 1970-01-01
          • 2016-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多