代码之家  ›  专栏  ›  技术社区  ›  Phil Young

简单的加法和减法不能正常工作

  •  2
  • Phil Young  · 技术社区  · 8 年前

    我继承了一个用PHP编写的项目,该项目有一个双条目风格的现金簿,它要求输入的金额等于输出的金额。

    当验证通过表单输入的数字(以确定它是否等于零)时,它会运行下面的代码,直到出现一个十进制数字,这似乎会使它随机掉落并返回错误的值。

    在下面的示例中,它返回了一个从53.87到53.87的非常小的数字,应该是零。这已经被剥离,以消除其他问题,所以我删除了很多输入验证等。

    <?php $inputs = array(
        array(
            "in" => '',
            "out" => '249.6',
        ),
        array(
            "in" => '',
            "out" => '396',
        ),
        array(
            "in" => '554.4',
            "out" => ''
        ),
        array(
            "in" => '145.07',
            "out" => ''
        ),
        array(
            "in" => '',
            "out" => '53.87',
        ),
    );
    $fTotal = 0;
    echo "Start at 0:   ";
    foreach($inputs as $key=>$sRef) {
        $itemValid = true;
        $aItem = array();
        $amountIn = $inputs[$key]['in'];
        $amountOut = $inputs[$key]['out'];
        if ($itemValid) {
            echo "'".$fTotal."'";
            $is_in = 0;
            if ($amountIn > 0.0) {
                $is_in = 1;
                echo "+";
                $amount = $amountIn;
                $fTotal = $fTotal + $amountIn;
            } else {
                $is_in = 0;
                echo "-";
                $amount = $amountOut;
                $fTotal = $fTotal - $amountOut;
            }
            echo "'".$amount."'=";
            echo "'".$fTotal."'   |   ";
            $aItem["is_in"] = $is_in;
            $aItem["amount"] = $amount;
            $aItems[] = $aItem;
        }
     }
    

    你可以在沙盒上运行这个 here .

    以下是预期输出:

    从0开始:“0”-“249.6”=“-249.6”|“-249.6'-“396”=”-645.6'|“-645.6'+”554.4“=”-91.2'|“-91.2'+”145.07“=”53.87“|”53.87'-“53.87”=“0”|

    以下是实际输出:

    从0开始:“0”-“249.6”=“-249.6”|“-249.6'-“396”=”-645.6“|”-645.6'+“554.4”=“-91.2”|”-91.2“+”145.07“=”53.87“|”53.87'-“53.87”=”-4.9737991503207E-14“|

    这里怎么了?

    使现代化

    根据下面的帮助, here's the working code 对于任何在未来遇到这种情况的人来说。

    2 回复  |  直到 8 年前
        1
  •  3
  •   billythekid    8 年前

    这是因为浮点(十进制)数学,计算机喜欢二进制数学。有时十进制数在二进制中没有很好的表示,所以会出现这些微小的差异。

    如果您可以声明每个数字都可以四舍五入到2个小数点,并且基于您有限的数据集,请将您的“总和”包装在 number_format($fTotal + $amountIn , 2) 等等可以帮你解决这个问题。

    或者,为了“更准确”,只需包装最后一个。 echo "'".number_format($fTotal, 2)."' | "; (或0或其他)

        2
  •  0
  •   John Corry    8 年前

    您的数字被解释为字符串。

    试试这个:

    <?php
    $inputs = array(
        array(
            "in" => 0,
            "out" => 249.6,
        ),
        array(
            "in" => 0,
            "out" => 396,
        ),
        array(
            "in" => 554.4,
            "out" => 0
        ),
        array(
            "in" => 145.07,
            "out" => 0
        ),
        array(
            "in" => 0,
            "out" => 53.87,
        ),
    );
    
    $fTotal = 0;
    
    echo "Start at 0:   ";
    foreach($inputs as $key => $sRef) {
        $itemValid = true;
    
        $amountIn = $sRef['in'];
        $amountOut = $sRef['out'];
    
        if ($itemValid) {
    
            echo $fTotal;
    
            $is_in = 0;
            if ($amountIn > 0.0) {
    
                $is_in = 1;
    
                echo "+";
    
                $amount = floatval($amountIn);
                $fTotal = floatval($fTotal) + floatval($amountIn);
    
            } else {
    
                $is_in = 0;
    
                echo "-";
    
                $amount = floatval($amountOut);
                $fTotal = floatval($fTotal) - floatval($amountIn);
    
            }
    
            echo $amount;
            echo ' = ' . $fTotal . "  |  ";
        }
    
    }