2010-12-06 7 views
8

Gießen Ich habe folgende sehr einfache Code -eine einfache Frage zu ganzen Zahlen in C++

int x=15000 
int z=0.7*x 
cout<<"z = "<<z<<endl; 

ich die Ausgabe

z=10499 

bekommen, aber wenn ich es ändern

zu
int z=0.7*15000 
cout<<"z = "<<z<<endl; 

Ausgänge

z=10500 

Ich verstehe, es hat etwas zu tun, mit z das Ergebnis zu int Casting aber warum ist es in beiden Fällen anders?

Dank,

EDIT - i Ubuntus bin mit 10.10 GCC

+0

Ich habe 10500 (gcc 4.2) ... welchen Compiler benutzen Sie? ist es genau der Code, den Sie haben? – Vladimir

Antwort

4

int z = 0,7 * x;

Der Wert 0,7 mit doppelter Genauigkeit ist nicht genau als Fließkommazahl darstellbar. Seine hexadezimale Darstellung ist 3fe6666666666666 auf den meisten Maschinen, was weniger ist als der wahre Wert 3fe6666666666666 ... Also ist das Ergebnis der doppelten Genauigkeit von 0,7 * x kleiner als sein wahrer Wert und wird abgerundet. Das ist richtiges Verhalten.

int z = 0,7 * 15000; Der Compiler andererseits ist schlau genug, um zu sehen, dass 0.7 * 15000 genau wie 7 * 1500 = 10500 dargestellt werden kann. Es verwendet also das korrekte Ergebnis anstelle des Ergebnisses, das durch das Kompilieren des Ausdrucks erhalten werden würde und es ausführen.

6

Ich nehme an, es ist wegen der Compiler bauen, die bei der Kompilierung arithmetische Ausdrücke vereinfacht.

Der erste Ausdruck wurde mit FPU (mit endlicher Genauigkeit) und der zweite mit Präprozessor (mit "unendlicher" Genauigkeit) berechnet. Versuchen Sie, das Programm im Freigabemodus auszuführen (oder mit -O2), die Ergebnisse sollten für beide Ausdrücke identisch sein.

3

Ich denke, Ruslik hat die richtige Antwort auf Ihre Frage.

Ich würde nur hinzufügen: Halten Sie immer Ihre Berechnungen entweder float oder double bis zum allerletzten Moment. So verlieren Sie nicht die Präzision.

Versuchen Sie, Ihren Code zu diesem Wechsel:

double z = 0.7 * 15000.0; 
cout<<"z = "<<z<<endl; // Will need to include some formatting 

oder

int z = (int) (0.7 * 15000.0); 
cout<<"z = "<<z<<endl; 
+1

Beide Vorschläge sind No-Ops und lösen das Problem nicht. – TonyK

+0

Das Problem ist, dass 0,7 * x ein anderes Ergebnis als 0,7 * 15000 ergibt. Siehe meine Antwort unten/oben. – TonyK

+1

Ich denke, das ist ein guter Rat. Wenn Sie doppelte Genauigkeit benötigen, behalten Sie Ihre Variablen im Doppel. Verwenden Sie gegebenenfalls als letzte Stufe die Rundung. –