相同变量的减法计算在不同情况下不同

时间:2017-03-20 11:56:31

标签: php math subtraction

问题有点严重。我需要的输出是2.9558577807620168e-12

1#working.php

 <?php 
     $a = 465.90928248188;
     $b = 15.651243716447;
     $c = 450.25803876543; 

     echo $a - $b -$c // output 2.9558577807620168e-12 as expected
 ?>

2#notworking.php

<?php 

     lot of arithmetic calculation almost 200-250 LoC
     $array1_28x1[3]; // 465.90928248188
     $array2_28x1[3]; // 15.651243716447
     $array3_28x1[3]; // 450.25803876543

     echo $array1_28x1[3] - $array2_28x1[3] - $array3_28x1[3];
     // output -4.5474735088646E-13

 ?>

我不明白这是什么问题。可以是内存泄漏吗?我已经一步一步调试,但找不到任何解决方案。这是非常重要的计算,所以甚至不能忽视。

注意:250 LoC下的变量值没有变化。我在减法之前已经转储了变量。

2 个答案:

答案 0 :(得分:5)

你确实使用了2次array2,所以我认为这是一个错字。 当我执行此代码时,它可以工作:

<?php 

     $array1_28x1[3] = 465.90928248188;
     $array2_28x1[3] = 15.651243716447;
     $array3_28x1[3] = 450.25803876543;

     echo $array1_28x1[3] - $array2_28x1[3] - $array3_28x1[3];
     // output 2.955857780762E-12

答案 1 :(得分:2)

问题出现,因为您只显示14位有效数字的中间变量。这隐藏了原始计算中存在但在重建中丢失的2个附加数字。

一般的解决方案是识别在浮点运算的范围内,你已经有效地计算了零。

要获得可重构的结果,您可以将中间结果转换为显示的字符串,然后将其转换回数字。这将为您提供可以从显示的中间结果中重现的结果。

对于具有基本上浮点噪声的结果并因此表示零,您的输入的比例/幅度为1000,这给出了绝对误差比例。 1e4*1e-16=1e-12的浮点噪声尺度。两个指示的结果都落在这个范围内,即两者都必须被认为是零。