PHP:字符串和浮点之间的求和问题
考虑这个数组PHP:字符串和浮点之间的求和问题,php,arrays,Php,Arrays,考虑这个数组 array(6) { ["id"]=> int(346058) ["amount"]=> string(5) "60.00" ["id_shop_where_transaction_is_done"]=> int(300) ["id_shop_where_money_come_from"]=> NULL ["negative_sum"]=> float(-60) ["negative"]=>
array(6) {
["id"]=>
int(346058)
["amount"]=>
string(5) "60.00"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["negative_sum"]=>
float(-60)
["negative"]=>
array(11) {
[0]=>
array(5) {
["id"]=>
int(346060)
["amount"]=>
string(5) "-2.20"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[1]=>
array(5) {
["id"]=>
int(348152)
["amount"]=>
string(5) "-7.50"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[2]=>
array(5) {
["id"]=>
int(350163)
["amount"]=>
string(5) "-7.70"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[3]=>
array(5) {
["id"]=>
int(351996)
["amount"]=>
string(5) "-5.20"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[4]=>
array(5) {
["id"]=>
int(353919)
["amount"]=>
string(5) "-5.00"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[5]=>
array(5) {
["id"]=>
int(354768)
["amount"]=>
string(5) "-2.50"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[6]=>
array(5) {
["id"]=>
int(356650)
["amount"]=>
string(5) "-5.00"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[7]=>
array(5) {
["id"]=>
int(361683)
["amount"]=>
string(5) "-5.00"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[8]=>
array(5) {
["id"]=>
int(361836)
["amount"]=>
string(5) "-7.50"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[9]=>
array(5) {
["id"]=>
int(364145)
["amount"]=>
string(5) "-7.90"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
[10]=>
array(5) {
["id"]=>
int(364426)
["amount"]=>
string(5) "-4.50"
["id_shop_where_transaction_is_done"]=>
int(300)
["id_shop_where_money_come_from"]=>
NULL
["id_referring_transaction"]=>
int(346058)
}
}
}
请稍作解释:
$array[0]['negative_sum']
是$array[0]['negative'][$i]['amount']的和。
(如果计算总和,则总和为-60。)
现在,我需要检查$array[0]['amount']是否是负和的>等等
$positive_amount = $transaction[$i]['amount'];
$negative_amount = $transaction[$i]['negative_sum'];
if ($positive_amount>abs($negative_amount)) {
$difference = -$positive_amount-$negative_amount;
var_dump($difference);
$data['difference'] = $difference;
}
首先,特定情况下的if代码不会执行,因为60不大于abs(-60)。但是它被执行了
第二,var_dump($difference)输出是
float(-7,105427357601E-15)
我不明白为什么。多谢各位
根据@OptimusCrime答案。我确实对代码做了一些修改。
$positive_amount = $transaction[$i]['amount'];
$negative_amount = $transaction[$i]['negative_sum'];
var_dump(number_format($positive_amount, 90));
var_dump(number_format($negative_amount, 90));
if ($positive_amount>abs($negative_amount)) {
$difference = -$positive_amount-$negative_amount;
var_dump($difference);
$data['difference'] = $difference;
}
该var_dump输出两个:
string(93) "60.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
string(94) "-60.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
浮点数很难正确表示。这样做的结果是,您无法始终确定浮点数中没有不重要的值。如图所示,您的数字总和计算为
-60.0
:
$sum = array_sum([-2.20, -7.50, -7.70, -5.20, -5.00, -2.50, -5.00, -5.00, -7.50, -7.90, -4.50]);
var_dump($sum); // float(-60)
但是,您没有看到真正的浮点值:
var_dump(number_format($sum, 22)); // string(26) "-59.9999999999999928945726"
这就是您稍后检查差异时出现问题的原因
处理浮点数时的一条规则是将它们与给定的增量进行比较:
if ((a - b) < delta)
if((a-b)
例如:
if (abs($sum - $total) < 0.0001)
if(绝对值($sum-$total)<0.0001)
然后阅读,其中有一条巨大的警告信息,以及专门用于与浮点值进行比较的部分。我理解您的答案,这似乎是正确的。但是,我确实放弃了积极和消极的东西。。。它们在第90位之前是相等的。…@Sinerba造成差异的是那些无关紧要的数字。您还可以将delta
变量变小很多,但是您不能执行float==float
,因为PHP不能保证看起来相同的两个浮点数实际上是相同的。我可以用简单的(舍入($正数,2))和舍入($负数,2)来求解吗?round
也会返回浮点数。您不能,不能,严格地相互比较浮动,因为不同的操作系统、体系结构(64/32位)等处理方式不同。阅读作为问题评论发布的链接。永远不要做float===float
。好的。尝试将您的解决方案移植到我的代码。如果(绝对值($sum-$total)<0.0001)。现在,我们有$positive=60.0000和$negative=-59.9999(来获取我的代码)。为了输入“if”部分,我需要输入:if($positive+$negative)>0.01,然后……好吗?