2010-11-01 4 views
5

je suis tombé sur un résultat inattendu en rond Int32.MaxValue déclenchement en System.Single:Pourquoi le CLR déborde-t-il d'Int32.MaxValue -> Single -> Int32, ce qui n'est pas le cas de la JVM?

Int32 i = Int32.MaxValue; 
Single s = i; 
Int32 c = (Int32)s; 

Debug.WriteLine(i); // 2147483647 
Debug.WriteLine(c); // -2147483648 

J'ai réalisé qu'il doit être débordait, puisque Single n'a pas assez de bits dans la mantisse pour maintenir la valeur Int32 et ça arrondit. Lorsque j'ai changé le conv.r4 en conv.r4.ovf dans le IL, un OverflowExcpetion est levé. Juste assez ...

Cependant, alors que je faisais des recherches sur cette question, j'ai compilé ce code en Java et couru et a obtenu les éléments suivants:

int i = Integer.MAX_VALUE; 
float s = (float)i; 
int c = (int)s; 

System.out.println(i); // 2147483647 
System.out.println(c); // 2147483647 

Je ne sais pas grand chose sur la machine virtuelle Java, mais Je me demande comment ça fait ça. Il semble beaucoup moins surprenant, mais comment conserve-t-il le chiffre supplémentaire après arrondi à 2.14748365E9? Est-ce qu'il conserve une sorte de représentation interne autour et ensuite le remplacer lors du renvoi à int? Ou est-ce simplement arrondi à Integer.MAX_VALUE pour éviter le débordement?

Répondre

3

Ce cas est explicitement traitée par §5.1.3 de la Java Language Specification:

Une conversion de rétrécissement d'un nombre à virgule flottante à un type intégrante T prend deux étapes:

  1. Dans la première étape, le nombre à virgule flottante est converti soit à un long, si T est long, ou à un int, si T est octet, court, char, ou int, comme suit:
    • Si le nombre à virgule flottante est NaN (§4.2.3), le résultat de la première étape de la conversion est un entier ou à long 0.
    • Sinon, si le nombre à virgule flottante n'est pas un infini, la valeur en virgule flottante est arrondi à une valeur entière V, arrondi vers zéro en utilisant IEEE 754 mode arrondi vers zéro (§4.2.3). Ensuite il y a deux cas:
      • Si T est longue, et cette valeur entière peut être représenté comme un long, le résultat de la première étape est la longue valeur V.
      • Dans le cas contraire, si cet entier la valeur peut être représentée comme un int, le résultat de la première étape est la valeur int V.
    • Dans le cas contraire, l'un des deux cas suivants doivent être remplies:
      • la valeur doit être trop petit (une valeur négative de grande ampleur ou infini négatif), et le résultat de la première étape est la plus petite valeur représentable de type int ou de long.
      • La valeur doit être trop grande (une valeur positive de grande ampleur ou infini positif), et le résultat de la première étape est la plus grande valeur représentable de type int ou longue.
+2

Quelle spé est-ce? – codekaizen

+0

Suivez le lien, Luke ... DaveE

+0

Ah, comment ces modifications rendent les commentaires apparaissent si différents que lors de la première publication. – codekaizen

Questions connexes