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

Subtraction calculation for the same variables differs in different situations

问题有点严重。我需要的输出是 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#不working.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 倍的 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

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

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

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

至于得到的结果本质上是浮点噪声,因此代表零,您的 scale/magnitude 输入是 1000,这给出了绝对误差比例。 1e4*1e-16=1e-12 的浮点噪声规模。两个指示的结果都在这个范围内,即两者都必须被认为是零。