J'ai le code simple suivant:
int speed1 = (int)(6.2f * 10);
float tmp = 6.2f * 10;
int speed2 = (int)tmp;
speed1
et speed2
devrait avoir la même valeur, mais en fait, j'ai:
speed1 = 61
speed2 = 62
Je sais que je devrais probablement utiliser Math.Round au lieu de cast, mais j'aimerais comprendre pourquoi les valeurs sont différentes.
J'ai regardé le bytecode généré, mais à part un magasin et une charge, les opcodes sont les mêmes.
J'ai également essayé le même code en java, et j'obtiens correctement 62 et 62.
Quelqu'un peut-il expliquer cela?
Edit: Dans le vrai code, ce n'est pas directement 6.2f * 10 mais un appel de fonction * une constante. J'ai le bytecode suivant:
pour speed1
:
IL_01b3: ldloc.s V_8
IL_01b5: callvirt instance float32 myPackage.MyClass::getSpeed()
IL_01ba: ldc.r4 10.
IL_01bf: mul
IL_01c0: conv.i4
IL_01c1: stloc.s V_9
pour speed2
:
IL_01c3: ldloc.s V_8
IL_01c5: callvirt instance float32 myPackage.MyClass::getSpeed()
IL_01ca: ldc.r4 10.
IL_01cf: mul
IL_01d0: stloc.s V_10
IL_01d2: ldloc.s V_10
IL_01d4: conv.i4
IL_01d5: stloc.s V_11
nous pouvons voir que les opérandes sont des flottants et que la seule différence est le stloc/ldloc
.
Pour ce qui est de la machine virtuelle, j'ai essayé avec Mono / Win7, Mono / MacOS et .NET / Windows, avec les mêmes résultats.