2014-10-04 19 views
6

Wenn ich Code in C++ schreiben:C++ Doppel zu lange lange

long long d = 999999998.9999999994; 
cout<<d; 

I Ausgabe: 999999999 (Aufrundung)

Aber Ausgabe dieses Codes:

long long d = 999999998.9999994994; 
cout<<d; 

ist 999999998 (Abrunden)

Hat es etwas mit Präzision zu tun. Gibt es eine Möglichkeit, die Präzision zu ändern? floor() Funktion gibt auch die gleiche Ausgabe.

Ich bemerkte auch, dass, wenn ich Wert 8.9999994994 oder 8.9999999994 zu d zuweisen (oben Variable). Ausgabe ist 8.

+0

Sie können explizit 0,5 hinzufügen und doppelt zu lange long. –

+0

C++ 11 Unterstützung? Benutzerdefinierte Literale könnten helfen. – Yakk

+0

@OleksandrVerhun Sie können dies tun, aber wenn es Ihr Ziel ist, die Fließkommazahl auf die nächste ganze Zahl zu runden, sollten Sie dies nicht tun. http://blog.frama-c.com/index.php?post/2013/05/02/nearestintf1 –

Antwort

10

999999998.9999999994 ist nicht genau darstellbare in double, so dass der Ist-Wert ist einer der zwei darstellbaren Zahlen auf jeder Seite der 999999998.9999999994 - entweder 999999998.99999988079071044921875 oder 999999999 (vorausgesetzt, IEEE-754 binary64-Format), in einer implementierungsspezifischen Weise ausgewählt. Die meisten Systeme werden standardmäßig auf die nächste Seite gerendert und produzieren 999999999.

Das Nettoergebnis ist, dass auf diesen Systemen, wenn Sie 999999998.9999999994 schreiben, endet es mit dem gleichen Effekt wie das Schreiben 999999999.0. Daher ergibt die nachfolgende Umwandlung 999999999 - die Umwandlung von einer Fließkommazahl in eine Ganzzahl wird immer abgeschnitten, aber hier gibt es nichts zu verkürzen.

Mit 999999998.9999994994 sind die nächstgelegenen darstellbaren Zahlen 999999998.999999523162841796875 und 999999998.99999940395355224609375. Entweder man erzeugt 999999998 nach dem Abschneiden. In ähnlicher Weise sind mit 8.9999999994 die nächstliegenden darstellbaren Zahlen 8.999999999399999950355777400545775890350341796875 und 8.9999999994000017267126168007962405681610107421875, und beide werden 8 nach dem Abschneiden produzieren.

4
long long d = 999999998.9999999994; 

Der nächste Wert 999999998.9999999994 dass double darstellen kann, ist 999999999.0 - denken Sie daran, dass Gleitpunkte endliche Genauigkeit hat;).
Daher bewirkt das Abschneiden der Dezimalstellen , und das ist, was in d gespeichert wird. long double eine höhere Genauigkeit hat -

eine wörtliche mit L -suffix Verwendung in der Tat zu 999999998 führt in d gespeichert werden.

long long d = 999999998.9999994994; 

Der nächste Wert 999999998.9999994994 dass double darstellen kann, ist tatsächlich unter 999999999 - etwa 999999998.999999523 auf meiner Maschine. Das Abschneiden der Dezimalstellen ergibt anschließend 999999998, und das wird in d gespeichert.