web-dev-qa-db-fra.com

C ++: Comment arrondir un double à un int?

Duplicate possible:
round () pour float en C++

J'ai un double (appelez-le x), censé être de 55 ans, mais en réalité stocké comme 54.99999999999999943157 que je viens de réaliser.

Alors quand je fais

double x = 54.999999999999943157;
int y = (int) x;

y = 54 au lieu de 55!

Cela m'a laissé perplexe pendant longtemps. Comment puis-je l'obtenir correctement?

86
midnightBlue

ajoutez 0,5 avant le casting (si x> 0) ou soustrayez 0,5 (si x <0), car le compilateur sera toujours tronqué.

float x = 55; // stored as 54.999999...
x = x + 0.5 - (x<0); // x is now 55.499999...
int y = (int)x; // truncated to 55

C++ 11 introduit également std :: round , qui utilise probablement une logique similaire pour ajouter 0,5 à | x | sous le capot (voir le lien si cela vous intéresse) mais est évidemment plus robuste.

Une question complémentaire pourrait être pourquoi le flottant n'est pas stocké exactement comme 55. Pour une explication, voir this stackoverflow answer .

111
Moritz

Le casting n'est pas une opération mathématique et ne se comporte pas comme tel. Essayer

int y = (int)round(x);
46
MK.

La conversion en un int tronque la valeur. L'ajout de 0.5 lui permet d'arrondir correctement.

int y = (int)(x + 0.5);
8
Pubby

Il est à noter que ce que vous faites n'est pas arrondi, c'est un casting. La conversion à l'aide de (int) x tronque la valeur décimale de x. Comme dans votre exemple, si x = 3.9995, le .9995 est tronqué et x = 3.

Comme proposé par beaucoup d’autres, une solution consiste à ajouter 0.5 à x, puis à convertir.

4
user1253795