29 votes

Comment fonctionne Double.intValue ()?

Ce code

 Double dbl = 254.9999999999999;
Integer integ = dbl.intValue();
System.out.println(integ);
 

affiche 254, mais un "9" de plus

 Double dbl = 254.99999999999999;
Integer integ = dbl.intValue();
System.out.println(integ);
 

et c'est déjà 255 .. Pourquoi?

30voto

assylias Points 102015

Pour connaître la valeur exacte de votre double, vous pouvez utiliser un BigDecimal:

 System.out.println(new BigDecimal(254.9999999999999));
System.out.println(new BigDecimal(254.99999999999999));
 

impressions:

 254.9999999999998863131622783839702606201171875
255
 

Donc, cela est simplement dû aux (limitations de) la double précision ...

13voto

Marko Topolnik Points 77257
System.out.println(254.9999999999999 == 255.0);
System.out.println(254.99999999999999 == 255.0);

imprime

false
true

Cela devrait vous donner un indice. L' double type peut représenter jusqu'à 16 chiffres significatifs, et votre littérale a 17. Par conséquent, l' double de la valeur la plus proche à la deuxième décimale littérale est - 255.0.

Pour la deuxième ligne de code, Eclipse en fait une mise en garde:

Comparant les expressions identiques

parce que c'est déjà le compilateur qui est conscient du fait que ce sont juste deux littéraux pour exactement le même double de la valeur.

4voto

Erwin Bolwidt Points 5566

Un double est un fichier binaire 64 bits à virgule flottante représentation d'un nombre. Binaire des nombres à virgule flottante ne peut pas représenter avec exactitude la plupart des fractions décimales. Ils peuvent représenter avec exactitude 1/2, 1/4, 1/64+1/32, etc, mais ils ne peuvent pas représenter avec exactitude 0.9 0.1. En outre, leur précision est limitée.

Dans votre cas, 254.99999999999999 a exactement la même représentation que 255.0 en interne. Vous pouvez voir cela en cochant une version hexadécimale de la version de la fraction binaire, à l'aide de l' Double.toHexString méthode. Parce que 254.99999999999999 est déjà égal à 255,0, lorsque vous coupez la partie fractionnaire par moulage d'un entier de 32 bits, vous vous retrouvez avec 255.

System.out.println("a: " + Double.toHexString(254.99999999999999d));
System.out.println("b: " + Double.toHexString(255d));

Sortie

a: 0x1.fep7
b: 0x1.fep7

3voto

Martijn Courteaux Points 33836

La réponse est assez simple. Le nombre décimal que vous avez écrit dans votre code avec un 9 plus est plus près du double qui représente exactement 255 que tout autre double. Ainsi, le double de ce qui est utilisé dans la compilation est exactement égale à 255. Alors que le nombre décimal avec un 9 moins est mieux représenté avec un double que je montre ci-dessous. Cela signifie qu'il se trouve plus près de deux fois plus que tout autre double.

Découvrez la démo: http://ideone.com/hSqJTJ

C'est la sortie:

Original double: 254.9999999999999
Cast to int: 254
Exact double: 254.9999999999998863131622783839702606201171875

Original double: 255.0
Cast to int: 255
Exact double: 255

3voto

Evgeniy Dorofeev Points 52031

le format binaire double est signe (1) + exposant (11) + fraction (53). La forme binaire pour 254.9999999999999 et 254.99999999999999 est

 0 10000000110 1111110111111111111111111111111111111111111111111100
0 10000000110 1111111000000000000000000000000000000000000000000000
 

nous pouvons l'obtenir en Long.toString(dbl.doubleToLongBits(dbl), 2);

la partie entière est

 1111110
1111111
 

1 bit de tête est omis, les valeurs entières réelles sont

 11111110 - 254
11111111 - 255
 

notez que le transtypage double en entier ne se fait pas en arrondissant mais en tronquant

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X