【问题标题】:Simple addition and subtraction not working correctly简单的加法和减法无法正常工作
【发布时间】:2016-04-18 13:20:06
【问题描述】:

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

当验证通过表单输入的数字时(计算它是否等于 0),它会运行下面的代码,该代码可以正常工作,直到出现一个十进制数字,这似乎使它随机翻倒并返回一个不正确的值。

在下面的示例中,它返回一个非常小的数字,从 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 供将来偶然发现此问题的任何人使用。

【问题讨论】:

    标签: php math addition subtraction


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

      试试这个:

      <?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 . "  |  ";
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-09
        • 2013-09-23
        • 2020-10-10
        • 1970-01-01
        相关资源
        最近更新 更多