Проблема немного критична. Выход мне нужен 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. Я сбросил переменные перед вычитанием.
Проблема возникает, так как вы отображаете свои промежуточные переменные только с 14 значащими цифрами. Это скрывает 2 дополнительные цифры, которые присутствуют в исходных вычислениях, но отсутствуют в реконструкции.
Общее решение состоит в том, чтобы признать, что в пределах арифметики с плавающей точкой вы фактически вычислили ноль.
Чтобы получить восстанавливаемый результат, вы можете преобразовать промежуточные результаты в отображаемые строки, а затем обратно в числа. Это тривиально даст вам результаты, которые можно воспроизвести из отображаемых промежуточных результатов.
Что касается результата, который по существу является шумом с плавающей запятой и, таким образом, представляет ноль, ваша шкала / величина входных данных равна 1000, что дает шкалу абсолютных ошибок, соответственно. шкала шума с плавающей точкой 1e4*1e-16=1e-12
, Оба указанных результата попадают в эту шкалу, то есть оба должны рассматриваться как нулевые.
Вы использовали 2 раза массив2, так что я думаю, что это опечатка.
когда я выполняю этот код, он работает:
<?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