2010-12-06 5 views
8

j'ai le code suivant très simple -une simple question sur la coulée des entiers en C++

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

je reçois la sortie

z=10499 

mais si je change à

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

sorties

z=10500 

je comprends qu'il a quelque chose à voir avec z coulée le résultat à int mais pourquoi est-ce différent dans les deux cas?

grâce,

EDIT - j'utilise construire de ubuntu 10.10 GCC

+0

J'ai 10500 (gcc 4.2) ... quel compilateur utilisez-vous? Est-ce exactement le code que vous avez? – Vladimir

Répondre

4

int z = 0,7 * x;

La valeur de précision double 0,7 n'est pas exactement représentable en tant que nombre à virgule flottante; sa représentation hexadécimale est 3fe6666666666666 sur la plupart des machines, ce qui est inférieur à la vraie valeur 3fe6666666666666 ... Donc le résultat en double précision de 0.7 * x est inférieur à sa vraie valeur, et est arrondi à la baisse. C'est un comportement correct.

int z = 0,7 * 15000; D'autre part, le compilateur est assez intelligent pour voir que 0.7 * 15000 est représentable exactement comme 7 * 1500 = 10500. Donc il utilise le résultat correct, au lieu du résultat qui serait obtenu en compilant l'expression et l'exécuter.

6

Je suppose qu'il est à cause du compilateur, qui simplifie les expressions arithmétiques au moment de la compilation.

La première expression a été calculée en utilisant FPU (avec une précision finie), et la seconde: par le préprocesseur (avec une précision "infinie"). Essayez d'exécuter le programme en mode édition (ou avec -O2), les résultats devraient être les mêmes pour les deux expressions.

3

Je pense que ruslik a la bonne réponse à votre question.

Je voudrais simplement ajouter: Toujours garder vos calculs en flottant ou en double jusqu'au tout dernier moment. De cette façon, vous ne perdez pas de précision.

Essayez de changer votre code à ceci:

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

ou

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

Ces deux suggestions sont no-ops, et ne font rien pour résoudre le problème. – TonyK

+0

Le problème est que 0.7 * x donne un résultat différent de 0.7 * 15000. Voir ma réponse ci-dessous/ci-dessus. – TonyK

+1

Je pense que c'est un bon conseil. Si vous avez besoin d'une double précision, gardez vos variables en double. Utilisez l'arrondi comme dernière étape, si nécessaire. –