Расчет вычитания для одних и тех же переменных отличается в разных ситуациях

Проблема немного критична. Выход мне нужен 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. Я сбросил переменные перед вычитанием.

1

Решение

Проблема возникает, так как вы отображаете свои промежуточные переменные только с 14 значащими цифрами. Это скрывает 2 дополнительные цифры, которые присутствуют в исходных вычислениях, но отсутствуют в реконструкции.

Общее решение состоит в том, чтобы признать, что в пределах арифметики с плавающей точкой вы фактически вычислили ноль.

Чтобы получить восстанавливаемый результат, вы можете преобразовать промежуточные результаты в отображаемые строки, а затем обратно в числа. Это тривиально даст вам результаты, которые можно воспроизвести из отображаемых промежуточных результатов.

Что касается результата, который по существу является шумом с плавающей запятой и, таким образом, представляет ноль, ваша шкала / величина входных данных равна 1000, что дает шкалу абсолютных ошибок, соответственно. шкала шума с плавающей точкой 1e4*1e-16=1e-12, Оба указанных результата попадают в эту шкалу, то есть оба должны рассматриваться как нулевые.

2

Другие решения

Вы использовали 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
5

По вопросам рекламы [email protected]