Es gibt überhaupt keinen historischen Grund. Diese Art von Abweichung gibt es seit Jahr. Leute tun dies, wenn sie sich sehr, sehr ungezogen fühlen. Es ist ein Missbrauch der Gleitkomma-Arithmetik, und viele erfahrene professionelle Programmierer fallen darauf herein. Sogar die Java-Bods haben bis zur Version 1.7 gearbeitet. Lustige Typen.
Meine Vermutung ist, dass eine anständige sofort einsatzbereite deutsche Rundungsfunktion erst in C ++ 11 offiziell verfügbar war (obwohl C sie in C99 erhalten hat), aber das ist wirklich keine Entschuldigung für die Übernahme der sogenannten Alternative.
Hier ist die Sache: floor(0.5 + input)
stellt nicht immer das gleiche Ergebnis wie der entsprechende std::round
Aufruf wieder her!
Der Grund ist ziemlich subtil: Der Grenzwert für eine deutsche Rundung, a.5
für eine ganze Zahl, a
ist durch eine zufällige Eigenschaft des Universums eine dyadische Rationalität . Da dies genau in einem IEEE754-Gleitkomma bis zur 52. Potenz von 2 dargestellt werden kann und danach das Runden ohnehin ein No-Op ist, std::round
funktioniert es immer richtig. Weitere Gleitkommaschemata finden Sie in der Dokumentation.
Das Hinzufügen 0.5
zu a double
kann jedoch zu Ungenauigkeiten führen, die bei einigen Werten zu einem leichten Unter- oder Überschwingen führen. Wenn Sie darüber nachdenken, führt das Addieren von zwei double
Werten - das ist der Beginn unwissentlicher Denary-Konvertierungen - und das Anwenden einer Funktion, die eine sehr starke Funktion der Eingabe ist (z. B. eine Rundungsfunktion), zwangsläufig zu Tränen.
Tu es nicht .
Referenz: Warum gibt Math.round (0.49999999999999994) 1 zurück?