Поширена думка, що числа з плаваючою комою не можна порівнювати за рівність, є неточною. Числа з плаваючою комою нічим не відрізняються від цілих чисел: якщо ви оціните "a == b", ви отримаєте істинні, якщо вони однакові числа, а помилкові - інакше (з розумінням того, що два NaN, звичайно, не однакові числа).
Справжня проблема полягає в наступному: якщо я зробив деякі розрахунки і не впевнений, що два числа, які я повинен порівняти, є абсолютно правильними, то що? Ця проблема однакова для плаваючої точки, як і для цілих чисел. Якщо ви оціните цілочисельний вираз "7/3 * 3", він не буде порівняти рівним "7 * 3/3".
Отже, припустимо, ми запитали "Як я порівняю цілі числа для рівності?" в такій ситуації. Єдиної відповіді немає; що ви повинні зробити, залежить від конкретної ситуації, зокрема, які помилки у вас є і що ви хочете досягти.
Ось кілька можливих варіантів.
Якщо ви хочете отримати "справжній" результат, якщо математично точні числа були б рівними, ви можете спробувати використати властивості обчислень, які ви виконуєте, щоб довести, що ви отримуєте однакові помилки в двох числах. Якщо це можливо, і ви порівнюєте два числа, які є результатами виразів, які давали б однакові числа, якщо обчислити точно, то ви отримаєте "правду" від порівняння. Інший підхід полягає в тому, що ви можете проаналізувати властивості обчислень і довести, що помилка ніколи не перевищує певну суму, можливо, абсолютну суму або величину відносно одного з входів або одного з результатів. У такому випадку ви можете запитати, чи відрізняються два обчислені числа щонайменше на цю суму, і повернути "справжнє", якщо вони знаходяться в інтервалі. Якщо ви не можете довести помилку, ви можете здогадатися і сподіватися на найкраще. Один із способів здогадки - це оцінити багато випадкових вибірок і побачити, який розподіл ви отримаєте в результатах.
Звичайно, оскільки ми встановлюємо лише вимогу, що ти отримаєш "справжній", якщо математично точні результати рівні, ми залишаємо відкритими можливість отримати "справжні", навіть якщо вони нерівні. (Насправді, ми можемо задовольнити цю вимогу, завжди повертаючи "справжнє". Це робить розрахунок простим, але, як правило, небажаним, тому я обговорюю покращення ситуації нижче.)
Якщо ви хочете отримати "хибний" результат, якщо математично точні числа були б неоднаковими, вам потрібно довести, що ваша оцінка чисел дає різні числа, якщо математично точні числа були б неоднаковими. Це може бути неможливим для практичних цілей у багатьох загальних ситуаціях. Тож розглянемо альтернативу.
Корисною вимогою може бути те, що ми отримуємо "помилковий" результат, якщо математично точні числа відрізняються більш ніж на певну суму. Наприклад, можливо, ми збираємося обчислити, куди їхав м'яч, кинутий у комп’ютерній грі, і ми хочемо знати, чи вдарив він у біту. У цьому випадку ми, безумовно, хочемо отримати "справжній", якщо м'яч вдарив битою, і ми хочемо отримати "помилковий", якщо м'яч далеко від бити, і ми можемо прийняти неправильну "справжню" відповідь, якщо м'яч в математично точне моделювання пропустило биту, але знаходиться в межах міліметра від удару кажана. У цьому випадку нам потрібно довести (або здогадатися / оцінити), що в нашому розрахунку положення м'яча і положення кажана є комбінована помилка не менше одного міліметра (для всіх цікавих позицій). Це дозволило б нам завжди повертатися "
Отже, те, як ви вирішите, що повернути, порівнюючи числа з плаваючою комою, дуже залежить від вашої конкретної ситуації.
Щодо того, як ви хочете довести межі помилок для розрахунків, це може бути складним предметом. Будь-яка реалізація з плаваючою комою, що використовує стандарт IEEE 754 в режимі "круглий-найближчий", повертає номер плаваючої точки, найближчий до точного результату для будь-якої основної операції (зокрема, множення, ділення, додавання, віднімання, квадратний корінь). (У випадку зв'язання, кругле, щоб низький біт був рівним.) (Будьте особливо обережні щодо квадратного кореня та поділу; ваша мовна реалізація може використовувати методи, які не відповідають IEEE 754 для них.) Через цю вимогу ми знаємо похибка в одному результаті становить щонайбільше 1/2 значення найменшого значущого біта. (Якби було більше, округлення перейшло б до іншого числа, яке знаходиться в межах 1/2 значення.)
Їхати звідти стає значно складніше; Наступним кроком є виконання операції, коли на одному з входів вже є помилка. Для простих виразів ці помилки можна дотримуватися через обчислення, щоб досягти межі кінцевої помилки. На практиці це робиться лише в кількох ситуаціях, наприклад, робота над якісною математичною бібліотекою. І, звичайно, потрібен точний контроль над тим, які саме операції виконуються. Мови високого рівня часто дають компілятору велику слабкість, тому ви можете не знати, в якому порядку виконуються операції порядку.
Існує набагато більше, що можна було б написати (і є) на цю тему, але я мушу зупинитися на цьому. Підсумовуючи відповідь, така відповідь є: Бібліотечна процедура не існує для цього порівняння, оскільки не існує єдиного рішення, яке б відповідало більшості потреб, яке варто включити в розпорядження бібліотеки. (Якщо порівняння з відносним або абсолютним інтервалом помилок вам достатньо, ви можете зробити це просто без бібліотечної програми.)