Найдите реальный пример ошибки с плавающей запятой - PullRequest
0 голосов
/ 01 августа 2020

Обычный совет, как обращаться с деньгами и другими десятичными числами, где точность имеет решающее значение, - использовать целые числа или строки (плюс библиотеки произвольной точности), и это имеет смысл, если вы понимаете, как работают математические вычисления с плавающей запятой. Однако у меня нет под рукой какого-либо конкретного примера c, чтобы проиллюстрировать это, поскольку каждый неправильный расчет, который я обнаружил в дикой природе, был связан с какой-то другой ошибкой: наивными сравнениями с использованием ==, отсутствием правильного округления при отображении результаты, явно неправильные logi c (например, расчет налогов с использованием непоследовательного алгоритма, который также не работает на бумаге) ... Я провел некоторое исследование, и результаты применимы только к C / C ++ (float / double с разной точностью ) или были просто пояснениями, почему нельзя доверять равенству двух чисел с плавающей запятой.

Можете ли вы поделиться автономным фрагментом кода PHP с тщательно подобранными числами с плавающей запятой и правильным алгоритмом, который отображает неправильный результат, явно вызванный ограничениями с плавающей запятой?

Отказ от ответственности: я не собираюсь спорить, опровергать или опровергать что-либо, мне, честно говоря, нужен пример для моего инструментария.

1 Ответ

1 голос
/ 01 августа 2020

Это лучшее, что у меня есть до сих пор (спасибо chtz за подсказку):

// Set-up and display settings (shouldn't affect internal calculations or final result)
set_time_limit(0);
ini_set('precision', -1);

// Expected accuracy: 2 decimal positions
$total = 0;
for ($i = 0; $i < 1e9; $i++) {
    $total += 0.01;
    // It's important to NOT round inside the loop, e.g.: $total = round($total + 0.01, 2);
}
var_dump($total, number_format($total, 2));
float(9999999.825158669)
string(12) "9,999,999.83" // Correct value would be "10,000,000.00"

К сожалению, это зависит от накопления очень большое количество ошибок точности (для этого требуется около 1 000 000 000 из них, а на моем P C требуется более 4 минут), поэтому это не так реально, как мне бы хотелось, но это, безусловно, иллюстрирует основная проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...