简单的加法和减法不能正常工作
Simple addition and subtraction not working correctly
我继承了一个用PHP写的项目,它有一个复式记账式的现金簿,要求进出的金额相等。
当验证通过表单输入的数字时(计算它是否为零),运行下面的代码在出现小数之前工作正常,这似乎使它随机掉落return 一个不正确的值。
在下面的示例中,它 return 是 53.87 - 53.87 之间的一个非常小的数字,应该是 zero.This 已被剥离以消除其他引起问题的因素,所以我删除了大量输入验证等
<?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。
这是预期的输出:
Start at 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' |
这是实际输出:
Start at 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
$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 . " | ";
}
}
这是因为浮点(十进制)数学而计算机喜欢二进制数学。有时十进制数字在二进制中没有很好的表示,因此会发生这些微小的差异。
如果您可以声明每个数字都可以四舍五入到小数点后两位,并且根据您有限的数据集,将您的 'sums' 包装在 number_format($fTotal + $amountIn , 2)
等中可以为您解决这个问题。
或者 "more accurate",只需包装最后一个,例如。 echo "'".number_format($fTotal, 2)."' | ";
(或 0 或其他)
我继承了一个用PHP写的项目,它有一个复式记账式的现金簿,要求进出的金额相等。
当验证通过表单输入的数字时(计算它是否为零),运行下面的代码在出现小数之前工作正常,这似乎使它随机掉落return 一个不正确的值。
在下面的示例中,它 return 是 53.87 - 53.87 之间的一个非常小的数字,应该是 zero.This 已被剥离以消除其他引起问题的因素,所以我删除了大量输入验证等
<?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。
这是预期的输出:
Start at 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' |
这是实际输出:
Start at 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
$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 . " | ";
}
}
这是因为浮点(十进制)数学而计算机喜欢二进制数学。有时十进制数字在二进制中没有很好的表示,因此会发生这些微小的差异。
如果您可以声明每个数字都可以四舍五入到小数点后两位,并且根据您有限的数据集,将您的 'sums' 包装在 number_format($fTotal + $amountIn , 2)
等中可以为您解决这个问题。
或者 "more accurate",只需包装最后一个,例如。 echo "'".number_format($fTotal, 2)."' | ";
(或 0 或其他)