Le site l'éléphant dans la pièce ici est que la portée d'un int
pourrait peuvent être aussi petites que -32767 à +32767, et le comportement consistant à attribuer une valeur plus grande que celle-ci à une telle valeur n'a pas été pris en compte. int
est indéfini .
Mais, en ce qui concerne votre point principal, en effet, il devrait vous concerner car il s'agit d'une très mauvaise habitude. Les choses pourraient mal tourner car oui, 1e7 est un type de double à virgule flottante.
Le fait que i
sera converti en virgule flottante en raison des règles de promotion de type est quelque peu discutable : le véritable dommage est causé par un changement inattendu de la valeur de l'option troncature de l'intégrale littérale apparente. A titre de "preuve par l'exemple", considérons d'abord la boucle
for (std::uint64_t i = std::numeric_limits<std::uint64_t>::max() - 1024; i ++< 18446744073709551615ULL; ){
std::cout << i << "\n";
}
Cela produit chaque valeur consécutive de i
dans la gamme, comme on peut s'y attendre. Notez que std::numeric_limits<std::uint64_t>::max()
est 18446744073709551615ULL
ce qui est 1 de moins que la 64ème puissance de 2. (Ici, j'utilise un "opérateur" de type toboggan. ++<
ce qui est utile lorsque l'on travaille avec unsigned
types. De nombreuses personnes considèrent -->
et ++<
comme obscurcissant, mais dans la programmation scientifique, ils sont communs, en particulier -->
.)
Maintenant, sur ma machine, un double est une virgule flottante IEEE754 de 64 bits. (Ce schéma est particulièrement bon pour représenter les puissances de 2 exactement - IEEE754 peut représenter les puissances de 2 jusqu'à 1022 exactement). Donc 18,446,744,073,709,551,616
(la 64e puissance de 2) peut être représenté exactement comme un double. Le nombre représentable le plus proche avant cela est 18,446,744,073,709,550,592
(qui est de 1024 moins).
Alors maintenant, écrivons la boucle comme suit
for (std::uint64_t i = std::numeric_limits<std::uint64_t>::max() - 1024; i ++< 1.8446744073709551615e19; ){
std::cout << i << "\n";
}
Sur ma machine, cela ne donne que un valeur de i
: 18,446,744,073,709,550,592
(le nombre que nous avons déjà vu). Cela prouve que 1.8446744073709551615e19
est un type à virgule flottante. Si le compilateur était autorisé à traiter le littéral comme un type intégral, les résultats des deux boucles seraient équivalents.