Проблема
Плаваюча точка не може точно зберігати всі десяткові значення. Тому при використанні форматів з плаваючою комою завжди будуть помилки округлення на вхідних значеннях. Помилки на входах, звичайно, призводять до помилок на виході. У випадку дискретної функції або оператора можуть бути великі відмінності на виході навколо точки, де функція або оператор є дискретними.
Введення та вихід для значень з плаваючою комою
Отже, використовуючи змінні з плаваючою комою, ви завжди повинні знати про це. І який би результат ви не хочете отримати з розрахунку з плаваючими точками, завжди слід форматувати / кондиціонувати перед тим, як показувати це на увазі.
Якщо використовуються лише безперервні функції та оператори, часто округлення до потрібної точності буде робити (не вкорочувати). Стандартні функції форматування, які використовуються для перетворення плавців у рядок, зазвичай роблять це для вас.
Оскільки округлення додає помилку, яка може призвести до того, що загальна помилка буде більше половини від бажаної точності, вихід повинен бути виправлений на основі очікуваної точності входів та бажаної точності виведення. Ти повинен
- Круглі введення до очікуваної точності або переконайтесь, що значення не можна вводити з більшою точністю.
- Додайте невелике значення до результатів перед їх округленням / форматуванням, яке менше або дорівнює 1/4 бажаної точності та більше, ніж максимальна очікувана помилка, викликана помилками округлення на вході та під час обчислення. Якщо це неможливо, поєднання точності використовуваного типу даних недостатньо для забезпечення бажаної точності виводу для вашого обчислення.
Ці 2 речі зазвичай не робляться, і в більшості випадків відмінності, спричинені тим, що не робити їх, занадто малі, щоб бути важливими для більшості користувачів, але у мене вже був проект, коли вихід не приймався користувачами без цих виправлень.
Дискретні функції або оператори (на зразок модуля)
Якщо задіяні дискретні оператори або функції, можуть знадобитися додаткові виправлення, щоб переконатися, що вихід є таким, як очікувалося. Округлення та додавання невеликих виправлень перед округленням не можуть вирішити проблему.
Можливо, потрібна спеціальна перевірка / корекція проміжних результатів обчислення, відразу після застосування дискретної функції або оператора. Для конкретного випадку (оператор модуля) дивіться мою відповідь на питання: Чому оператор модуля повертає дробовий номер у javascript?
Краще уникати проблем
Часто набагато ефективніше уникнути цих проблем, використовуючи типи даних (цілі чи формати фіксованої точки) для таких обчислень, які можуть зберігати очікуваний вхід без помилок округлення. Прикладом цього є те, що ви ніколи не повинні використовувати значення з плаваючою комою для фінансових розрахунків.
0.1
кінцеве двійкове число з плаваючою точкою.