J'ai remarqué un comportement intéressant avec le float arrondi / troncature du compilateur C #. À savoir, lorsqu'un littéral à flotteur est au-delà de la gamme de représentations garantis (7 chiffres décimaux), puis a) la coulée explicitement d'un flotteur pour flotter (une opération sémantiquement inutile) et B) stocker le calcul intermédiaire entraîne une variable locale. Un exemple: La sortie est la suivante: p> dans la construction de débogage discipé sur mon ordinateur, B est calculé comme suit: p> tandis que D est calculé comme p> enfin, ma question: Pourquoi la deuxième ligne de la sortie est-elle différente du quatrième ? Est-ce que cette fmul supplémentaire fait une telle différence? Notez également que si le dernier chiffre (déjà non représentable) du flotteur F est retiré ou même réduit, tout "tombe en place". P> p>
3 Réponses :
Votre question peut être simplifiée pour demander pourquoi ces deux résultats sont différents: Si vous regardez le code dans le réflecteur .NET, vous pouvez voir que le code ci-dessus est en fait compilé comme si Il s'agissait du code suivant: p> Console.WriteLine(204);
Console.WriteLine(205);
Donc, vous dites que la raison est que (int) est fait par troncature et (flotteur) signifie arrondir. Si tel est le cas, alors pourquoi la sortie est-elle différente pour la console.writewrineline (((2.0499999F * 100f)) et la console.write ((int) (flotteur) (2.0499999F * 100F))?
@Alan, vérifiez ma réponse. La raison est que le flotteur ne peut contenir que 7 chiffres. Journal (2 ^ 23) = 6.9
@Alan: Lorsque vous utilisez des constantes codées durement, les calculs sont entièrement effectués dans le compilateur et à l'aide des règles du compilateur, pas dans le fichier d'exécution .NET.
@Andrey, merci. Je sais que le flotteur dépasse la plage représentable (voir question, je n'ai pas modifié cette partie), mais ensuite, avec votre confirmation, cela semble un peu effrayant pour moi - jetant un flotteur pour flotter ne devrait pas faire une différence, mais dans cette cas, ça fait.
@Mark: Ces règles sont-elles différentes? Et si oui, suis-je censé le savoir, soit du Doc de référence de langue C #, soit MSDN, soit-ce que c'est juste une divergence occasionnelle entre le compilateur et le temps d'exécution?
@Alan: Apparemment, ils sont différents que votre exemple montre. Je pense en général si vous appuyez sur le chiffre le moins important d'un calcul de point flottant est une idée incroyablement mauvaise.
@Mark: Bien sûr. Merci pour votre réponse.
Mark a raison sur le compilateur. Maintenant, trompons le compilateur: première expression n'a pas de sens mais empêche le compilateur de l'optimisation. Le résultat est le suivant: p> OK, j'ai trouvé l'explication. P> si vous modifiez sur 2.0499999F code> ne peut pas être stocké comme float, car Il ne peut contenir que 7 chiffres à base de 10. Et ce littéral est de 8 chiffres, le compilateur a donc arrondi parce que ne pouvait pas stocker. (devrait donner un avertissement imo) p>
2.049999F code> résultat sera attendu. p> p>
Merci Andrey, j'ai choisi la réponse de Mark sur la base des informations de compilation VS Runtime, mais la vôtre est également pertinente.
Dans un commentaire que vous avez demandé p>
Ces règles sont-elles différentes? p> blockQuote>
oui. Ou plutôt, les règles permettent de comportement différent. P>
Et si oui, suis-je censé le savoir, soit du Doc de référence de langue C #, soit MSDN, soit-ce que c'est juste une divergence occasionnelle entre le compilateur et l'exécution p> blockQuote>
C'est impliqué par la spécification. Les opérations de point flottant ont un certain niveau minimum de précision qui doit être rempli, mais le compilateur ou l'exécution est autorisé à utiliser plus em> précision s'il voit l'ajustement. Cela peut provoquer des changements importants et observables lorsque vous effectuez des opérations qui magnifient les petits changements. L'arrondi, par exemple, peut transformer un changement extrêmement petit en un extrêmement grand. P>
Ce fait conduit à des questions relativement fréquemment posées ici. Pour certains contextes sur cette situation et d'autres situations pouvant produire des divergences similaires, voir les éléments suivants: P>
Pourquoi ce calcul de point flottant donne-t-il des résultats différents sur différentes machines? P>
C # XNA Visual Studio: différence entre les modes "Libération" et "Débogage"? P>
Eric, merci beaucoup. Votre dernier lien était particulièrement éclairant. En fait, j'ai cherché des scénarios similaires avant de poster la question, mais apparemment, ma portée était trop étroite.
J'ai vu une réponse à cette question ici mais je ne peux pas le trouver