简单算术中的奇怪行为

时间:2012-03-03 14:23:33

标签: php math floating-point

  

可能重复:
  Strange addition of numeric strings in PHP

$r = 1.0 - 0.8 - 0.2;
var_dump($r);

我得漂浮-5.5511151231258E-17。 我在C ++和C#中得到的结果相同。

MySQL我通过查询获得结果0.0:

SELECT 1.0 - 0.8 - 0.2

2 个答案:

答案 0 :(得分:8)

请注意:0.8具有十进制的有限表示,因为它具有值8/10¹

但是在基数2中,它有值:1/2 + 1/4 + 0/8 + 0/16 + 1/32 + 1/64 + 0/128 + ......它没有结束,就像三分之一没有十进制表示结束(0.333…),但在基数3中为0.1

0.8 = 0.110011001100110011001100... in binary
0.2 = 0.001100110011001100110011... in binary

您的计算机以二进制表示形式存储浮点值。因此,当您添加,减去,乘以等数字时,精度会降低。

C ++,C和C#是编译语言,浮点数通常存储在4或8个字节中。你不能在浮动中存储0.8。

MySQL可能会告诉你0因为它会截断计算结果。

如果您想要一个在任何基础上执行计算而不会损失精度的库,请查找GMPlib。

答案 1 :(得分:3)

您可以使用BCMathbcsub()来避免此情况)。或者你可以简单地round()(注意你可以在第二个参数上设置精度)。对于所有情况,您将收到-0,如果您需要肯定0,请使用abs()

了解我所谈论的here

代码示例

<?php

    echo 'Direct: ' . ( 1.0 - 0.8 - 0.2 ) . '<br/>';

    echo 'BC Math: ' . bcsub( bcsub('1.0', '0.8'), '0.2' ) . '<br/>';
    echo 'Round: ' . round( 1.0 - 0.8 - 0.2 ) . '<br/>';
    echo 'Absolute: ' . abs( round( 1.0 - 0.8 - 0.2 ) ) . '<br/>';

?>