En Java, que se passe-t-il lorsque vous incrémentez un int (ou octet / short / long) au-delà de sa valeur maximale? Est-ce qu’il enveloppe la valeur négative maximale?
AtomicInteger.getAndIncrement () se comporte-t-il également de la même manière?
A partir de la section Spécification du langage Java sur les opérations entières :
Les opérateurs entiers intégrés n’indiquent aucun débordement ni débordement.
Les résultats sont spécifiés par la langue et indépendamment de la version de JVM: Integer.MAX_VALUE + 1 == Integer.MIN_VALUE
et Integer.MIN_VALUE - 1 == Integer.MAX_VALUE
. La même chose vaut pour les autres types d’entiers.
Les objects entiers atomiques ( AtomicInteger
, AtomicLong
, etc.) utilisent en interne les opérateurs entiers normaux, ainsi getAndDecrement()
, etc.
Si vous faites quelque chose comme ça:
int x = 2147483647; x++;
Si vous imprimez maintenant x, ce sera la valeur -2147483648
Comme le dit jterrace, le runtime Java “encapsulera” le résultat dans Integer.MIN_VALUE de -2147483648.
Mais c’est mathématiquement incorrect! La réponse mathématique correcte est 2147483648. Mais un «int» ne peut pas avoir une valeur de 2147483648. Les limites «int» sont -2147483648 à 2147483647.
Alors, pourquoi Java ne lance-t-il pas une exception? Bonne question! Un object Array serait.
Mais les auteurs de la langue connaissent la scope de leurs types primitifs, ils utilisent donc la technique de «wrapping» pour éviter une exception coûteuse.
En tant que développeur, vous devez tester ces limites de type. Un test simple pour l’incrémentation serait
if(x++ == Integer.MIN_VALUE) //boundary exceeded
Un simple test de décrémentation serait
if(x-- == Integer.MAX_VALUE) //boundary exceeded
Un test complet pour les deux serait
if(x++ == Integer.MIN_VALUE || x-- == Integer.MAX_VALUE) //boundary exceeded
Ce qui se passe est qu’un bit supplémentaire est ajouté au bit le plus à droite et que l’ordre décroît comme un signe signé négativement … Notez ce qui se passe après ‘int_32’;
int _0 = 0b0000000000000000000000000000000; int _1 = 0b0000000000000000000000000000001; int _2 = 0b0000000000000000000000000000010; int _3 = 0b0000000000000000000000000000100; int _4 = 0b0000000000000000000000000001000; int _5 = 0b0000000000000000000000000010000; int _6 = 0b0000000000000000000000000100000; int _7 = 0b0000000000000000000000001000000; int _8 = 0b0000000000000000000000010000000; int _9 = 0b0000000000000000000000100000000; int _10 = 0b0000000000000000000001000000000; int _11 = 0b0000000000000000000010000000000; int _12 = 0b0000000000000000000100000000000; int _13 = 0b0000000000000000001000000000000; int _14 = 0b0000000000000000010000000000000; int _15 = 0b0000000000000000100000000000000; int _16 = 0b0000000000000001000000000000000; int _17 = 0b0000000000000010000000000000000; int _18 = 0b0000000000000100000000000000000; int _19 = 0b0000000000001000000000000000000; int _20 = 0b0000000000010000000000000000000; int _21 = 0b0000000000100000000000000000000; int _22 = 0b0000000001000000000000000000000; int _23 = 0b0000000010000000000000000000000; int _24 = 0b0000000100000000000000000000000; int _25 = 0b0000001000000000000000000000000; int _26 = 0b0000010000000000000000000000000; int _27 = 0b0000100000000000000000000000000; int _28 = 0b0001000000000000000000000000000; int _29 = 0b0010000000000000000000000000000; int _30 = 0b0100000000000000000000000000000; int _31 = 0b1000000000000000000000000000000; int _32 = 0b1111111111111111111111111111111; int _XX = 0b10000000000000000000000000000000; // numeric overflow. int _33 = 0b10000000000000000000000000000001; int _34 = 0b11000000000000000000000000000000; int _35 = 0b11100000000000000000000000000000; int _36 = 0b11110000000000000000000000000000; int _37 = 0b11111000000000000000000000000000; int _38 = 0b11111100000000000000000000000000; int _39 = 0b11111110000000000000000000000000; int _40 = 0b11111111000000000000000000000000; int _41 = 0b11111111100000000000000000000000; int _42 = 0b11111111110000000000000000000000; int _43 = 0b11111111111000000000000000000000; int _44 = 0b11111111111100000000000000000000; int _45 = 0b11111111111110000000000000000000; int _46 = 0b11111111111111000000000000000000; int _47 = 0b11111111111111100000000000000000; int _48 = 0b11111111111111110000000000000000; int _49 = 0b11111111111111111000000000000000; int _50 = 0b11111111111111111100000000000000; int _51 = 0b11111111111111111110000000000000; int _52 = 0b11111111111111111111000000000000; int _53 = 0b11111111111111111111100000000000; int _54 = 0b11111111111111111111110000000000; int _55 = 0b11111111111111111111111000000000; int _56 = 0b11111111111111111111111100000000; int _57 = 0b11111111111111111111111110000000; int _58 = 0b11111111111111111111111111000000; int _59 = 0b11111111111111111111111111100000; int _60 = 0b11111111111111111111111111110000; int _61 = 0b11111111111111111111111111111000; int _62 = 0b11111111111111111111111111111100; int _63 = 0b11111111111111111111111111111110; int _64 = 0b11111111111111111111111111111111; System.out.println( " _0 = " + _0 ); System.out.println( " _1 = " + _1 ); System.out.println( " _2 = " + _2 ); System.out.println( " _3 = " + _3 ); System.out.println( " _4 = " + _4 ); System.out.println( " _5 = " + _5 ); System.out.println( " _6 = " + _6 ); System.out.println( " _7 = " + _7 ); System.out.println( " _8 = " + _8 ); System.out.println( " _9 = " + _9 ); System.out.println( " _10 = " + _10 ); System.out.println( " _11 = " + _11 ); System.out.println( " _12 = " + _12 ); System.out.println( " _13 = " + _13 ); System.out.println( " _14 = " + _14 ); System.out.println( " _15 = " + _15 ); System.out.println( " _16 = " + _16 ); System.out.println( " _17 = " + _17 ); System.out.println( " _18 = " + _18 ); System.out.println( " _19 = " + _19 ); System.out.println( " _20 = " + _20 ); System.out.println( " _21 = " + _21 ); System.out.println( " _22 = " + _22 ); System.out.println( " _23 = " + _23 ); System.out.println( " _24 = " + _24 ); System.out.println( " _25 = " + _25 ); System.out.println( " _26 = " + _26 ); System.out.println( " _27 = " + _27 ); System.out.println( " _28 = " + _28 ); System.out.println( " _29 = " + _29 ); System.out.println( " _30 = " + _30 ); System.out.println( " _31 = " + _31 ); System.out.println( " _32 = " + _32 ); System.out.println( " _xx = " + _xx ); // -2147483648 System.out.println( " _33 = " + _33 ); System.out.println( " _34 = " + _34 ); System.out.println( " _35 = " + _35 ); System.out.println( " _36 = " + _36 ); System.out.println( " _37 = " + _37 ); System.out.println( " _38 = " + _38 ); System.out.println( " _39 = " + _39 ); System.out.println( " _40 = " + _40 ); System.out.println( " _41 = " + _41 ); System.out.println( " _42 = " + _42 ); System.out.println( " _43 = " + _43 ); System.out.println( " _44 = " + _44 ); System.out.println( " _45 = " + _45 ); System.out.println( " _46 = " + _46 ); System.out.println( " _47 = " + _47 ); System.out.println( " _48 = " + _48 ); System.out.println( " _49 = " + _49 ); System.out.println( " _50 = " + _50 ); System.out.println( " _51 = " + _51 ); System.out.println( " _52 = " + _52 ); System.out.println( " _53 = " + _53 ); System.out.println( " _54 = " + _54 ); System.out.println( " _55 = " + _55 ); System.out.println( " _56 = " + _56 ); System.out.println( " _57 = " + _57 ); System.out.println( " _58 = " + _58 ); System.out.println( " _59 = " + _59 ); System.out.println( " _60 = " + _60 ); System.out.println( " _61 = " + _61 ); System.out.println( " _62 = " + _62 ); System.out.println( " _63 = " + _63 ); System.out.println( " _64 = " + _64 );
Si un ajout d’entier déborde, le résultat est les bits de poids faible de la sum mathématique tels que représentés dans un format de complément à deux suffisamment grand. Si un débordement se produit, le signe du résultat n’est pas le même que le signe de la sum mathématique des deux valeurs d’opérande.
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510
Ceci est une solution de contournement afin que vous puissiez toujours continuer fondamentalement à l’infini. Je recommande un if (int> nearmax) puis passe à new int Exemple:
int x = 2000000000; x++; int stacker = 0; if (x > 2000000000) { int temp = x; x = temp - 2000000000 stacker++; }
alors vous pouvez vous désemstackr si nécessaire aussi …
dis x = 0
x--; if (x < 0 && stacker > 0) { int temp = x; x = 2000000000 + temp;//plus because it's negative stacker--; }
cela donne 2000000000 x 2000000000 et je veux dire … vous pouvez continuer à le faire alors …
Bien sûr, vous pouvez aller plus loin si vous voulez utiliser des nombres négatifs …