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?
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 .
Le casting n'est pas une opération mathématique et ne se comporte pas comme tel. Essayer
int y = (int)round(x);
La conversion en un int
tronque la valeur. L'ajout de 0.5
lui permet d'arrondir correctement.
int y = (int)(x + 0.5);
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.