Betrachten Sie den folgenden Code-Snippet:Wie gehen printf und scanf mit Fließkomma-Präzisionsformaten um?
float val1 = 214.20;
double val2 = 214.20;
printf("float : %f, %4.6f, %4.2f \n", val1, val1, val1);
printf("double: %f, %4.6f, %4.2f \n", val2, val2, val2);
Welche Ausgänge:
float : 214.199997, 214.199997, 214.20 | <- the correct value I wanted
double: 214.200000, 214.200000, 214.20 |
Ich verstehe, dass 214.20
eine unendliche binäre Darstellung hat. Die ersten beiden Elemente der ersten Linie eine Annäherung des beabsichtigten Wert haben, aber die die letzte scheint überhaupt keine Annäherung zu haben, und dies führte mich auf die folgende Frage:
Wie das tun scanf
, fscanf
, printf
, fprintf
(usw.) Funktionen behandeln die Präzisionsformate?
Ohne Genauigkeit zur Verfügung gestellt, printf
ausgedruckt einen angenäherten Wert, aber mit %4.2f
gab es das richtige Ergebnis. Können Sie mir den Algorithmus erklären, mit dem diese Funktionen die Genauigkeit handhaben?
Danke für die Beantwortung, obwohl meine Frage immer noch am selben Ort ist. In erster Linie selbst könnte der Float NICHT den exakten Wert von 214,20 enthalten, dann wie könnte er ihn NUR mit% 4.2f Genauigkeit und NICHT mit% 4.6f wiedergewinnen. Was hat es getan, um den Wert wiederzuerlangen? Ich verstehe, dass eine Annäherung gemacht wird, aber WAS WAR DAS BIT-MUSTER, DAS INNERHALB DES GESPEICHERTEN 214.199997 VERURSACHT HATTE, 214.20 ZU WERDEN, UND WIE WURDEN WIR ANGEKOMMEN? –
Nicht sicher, dass ich dich bekomme, aber das ist nur die [Rundung] (http://en.wikipedia.org/wiki/Rounding). Es ist pure Chance, dass '% 4.2f' Ihnen genau den Wert gibt, den Sie wollten. Es ist immer noch "falsch", da die Binärdarstellung * nicht * 214.20, sondern 214.1999969482421875 entspricht. Wenn Sie jetzt "214.1999969482421875" auf 6 Ziffern runden, erhalten Sie "214.199997", weil die 7. Ziffer eine 9 ist und aus der 6 eine 7 wird. Aber wenn Sie nur auf 2 Ziffern runden, erhalten Sie "214.20" wegen der 3. Ziffer ist eine Neun, also müssen Sie die 9 auf der 2. Stelle erhöhen. Das "überläuft" bis 10 und verwandelt die ".19" in ".20". – DarkDust
Oh !! Ich glaube, Sie versuchen zu sagen, dass diese Operation in dezimaler Darstellung erfolgt, und so wurde 214.199997 als ein Rundungseffekt doppelter Genauigkeit gebildet. Weil es in binärer Darstellung gewesen war, haben wir bereits bestätigt, dass 214.20 NICHT binär darstellbar ist, mit allen verwendeten Rundungsfähigkeiten. –