1
votes

Pourquoi la conversion double en int ne fonctionne-t-elle pas comme prévu en Java?

J'ai commencé à lire la documentation de Java8 et j'ai essayé différents exemples de codes. Trouvé sous un comportement étrange.

Sample1

Double di = new Double(Math.pow(2,32-1)) - 1.0;
System.out.printf("%f\n",di.doubleValue()); //2147483647.000000
int a= di.intValue();
System.out.println(a); //2147483647

Sample2

Double di = new Double(Math.pow(2,32-1));
System.out.printf("%f\n",di.doubleValue()); //2147483648.000000
int a= di.intValue();
System.out.println(a); //2147483647

Comment se fait-il dans les deux cas, la valeur int renvoie la même valeur?


1 commentaires

Essayez System.out.println (Integer.MAX_VALUE); ... maintenant essayez System.out.println (Integer.MAX_VALUE + 1); - quel résultat voudriez-vous de quoi est-ce effectivement cela?


3 Réponses :


0
votes
La valeur de

int ne peut pas dépasser Integer.MAX_VALUE , qui est exactement 2147483647 . Vous abandonnez volontairement toutes les queues lorsque vous appelez intValue () .


0 commentaires

1
votes

Veuillez consulter https : //docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3 La partie importante mise en évidence en gras à la fin:

Une conversion restrictive d'un nombre à virgule flottante en un type entier T prend deux étapes:

Dans la première étape, le nombre à virgule flottante est converti en un long, si T est long, ou en un int, si T est un octet, un court, un char ou un 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 un 0 long.

Sinon, si le nombre à virgule flottante n'est pas une infinité, la valeur à virgule flottante est arrondie à une valeur entière V, arrondie vers zéro en utilisant le mode arrondi vers zéro IEEE 754 (§4.2.3). Ensuite, il y a deux cas:

Si T est long et que cette valeur entière peut être représentée comme un long, alors le résultat de la première étape est la valeur longue V.

Sinon, si cette valeur entière peut être représentée comme un entier, alors le résultat de la première étape est la valeur int V.

Sinon, l'un des deux cas suivants doit être vrai:

La valeur doit être trop petite (une valeur négative de grande magnitude ou une valeur infinie négative), et le résultat de la première étape est la plus petite valeur représentable de type int ou long.

La valeur doit être trop grande (une valeur positive de grande magnitude ou une valeur infinie positive) et le résultat de la première étape est la plus grande valeur représentable de type int ou long.

Cela dit, votre double valeur est 2147483648 (vous pouvez essayer avec un nombre plus élevé). La plus haute valeur représentable int int est 2147483647. C'est pourquoi vous vous retrouvez avec 2147483647.


0 commentaires

0
votes

En effet, la valeur maximale du type int en Java est 2147483647 . Lorsque vous invoquez Double :: doubleValue , il effectuera une conversion restrictive si la valeur que vous essayez de convertir est hors limite et qu'elle est indiquée par docs :

Renvoie la valeur de ce Double comme un entier après une conversion primitive de rétrécissement.

Et il pointe même vers JLS 5.1.3 où cette conversion restreinte est décrite.

La conversion des valeurs à virgule flottante s'effectue en deux étapes. La raison pour laquelle vous voyez cette valeur est expliquée dans la phrase de la première étape, point trois, option b:

La valeur doit être trop grande (une valeur positive de grande amplitude ou une valeur infinie positive) et le résultat de la première étape est la plus grande valeur représentable de type int ou long.

Une conversion restrictive d'un nombre à virgule flottante en un type entier T prend deux étapes:

  1. Dans la première étape, le nombre à virgule flottante est converti soit en un long, si T est long, soit en un int, si T est un octet, un court, un char ou un 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 un 0 long.

    • Sinon, si le nombre à virgule flottante n'est pas une infinité, la valeur à virgule flottante est arrondie à une valeur entière V, arrondie vers zéro en utilisant le mode arrondi vers zéro IEEE 754 (§4.2.3) . Ensuite, il y a deux cas:

    • a Si T est long, et que cette valeur entière peut être représentée comme un long, alors le résultat de la première étape est la valeur longue V.

    • b Sinon, si cette valeur entière peut être représentée par un entier, alors le résultat de la première étape est la valeur int V.

    • Sinon, l'un des deux cas suivants doit être vrai:

    • a La valeur doit être trop petite (une valeur négative de grande amplitude ou une valeur infinie négative), et le résultat de la première étape est la plus petite valeur représentable de type int ou long.

    • b La valeur doit être trop grande (une valeur positive de grande amplitude ou une valeur infinie positive) et le résultat de la première étape est la plus grande valeur représentable de type int ou long.

  2. Dans la deuxième étape:

    • Si T est un entier ou long, le résultat de la conversion est le résultat de la première étape.

    • Si T est un octet, un caractère ou un court, le résultat de la conversion est le résultat d'une conversion restrictive en type T (§5.1.3) du résultat de la première étape.

      < / li>

Le résultat sera donc la plus grande valeur représentable de type int , dans ce cas.


0 commentaires