Історичної причини взагалі немає. Цей вид відхилення існує з року в рік. Люди роблять це, коли вони почуваються дуже, дуже неслухняними. Це зловживання арифметикою з плаваючою комою, і багато досвідчених професійних програмістів на це попадаються. Навіть боди Java робили до версії 1.7. Кумедні хлопці.
Моя здогадка полягає в тому, що гідна нестандартна функція німецького округлення формально була доступна лише до C ++ 11 (незважаючи на те, що C отримав їх у C99), але це насправді не є виправданням для прийняття так званої альтернативи.
Ось у чому річ: floor(0.5 + input)
не завжди відновлюється той самий результат, що і відповідний std::round
виклик!
Причина досить тонка: гранична точка для німецького округлення, a.5
оскільки ціле число a
є, за випадковою властивістю Всесвіту, діадичним раціоналом . Оскільки це може бути представлено в точності з плаваючою точкою IEEE754 до 52-ї степені 2, а в подальшому округлення в будь-якому випадку не std::round
діє , завжди працює належним чином. Інші схеми з плаваючою комою див. У документації.
Але додаючи 0.5
до double
банки може ввести неточність, що спричиняє незначне заниження або перевищення деяких значень. Якщо ви задумаєтесь, додавши два double
значення разом - це початок мимовільних конверсій денара - і застосувавши функцію, яка є дуже сильною функцією введення (наприклад, функцією округлення), обов’язково закінчиться сльозами.
Не роби цього .
Довідково: Чому Math.round (0.49999999999999994) повертає 1?