2011-02-27 28 views
41

En Java, ¿qué sucede cuando se incrementa un int (o byte/corto/largo) más allá de su valor máximo? ¿Se ajusta al máximo valor negativo?¿Qué sucede cuando se incrementa un número entero más allá de su valor máximo?

¿AtomicInteger.getAndIncrement() también se comporta de la misma manera?

+0

[Este PDF] (http://pages.cs.wisc.edu/~willb/cs302/spring-07/why-integer-overflow-cl.pdf) dan una explicación clara de cómo/por qué funciona Sí, la versión atómica hará lo mismo. – TofuBeer

Respuesta

53

Desde el Java Language Specification section on integer operations:

El built-in los operadores enteros no indican desbordamiento o subdesbordamiento en cualquier forma .

Los resultados son especificadas por el lenguaje e independiente de la versión de la JVM: Integer.MAX_VALUE + 1 == Integer.MIN_VALUE y Integer.MIN_VALUE - 1 == Integer.MAX_VALUE. Lo mismo ocurre con los otros tipos de enteros.

Los objetos enteros atómicos (AtomicInteger, AtomicLong, etc.) utilizan internamente los operadores enteros normales, por lo que getAndDecrement(), etc. también se comportan de esta manera.

7

Si haces algo como esto:

int x = 2147483647; 
x++; 

Si ahora imprimir x, será el valor -2147483648

+0

¿Qué sucede con x en el nivel binario cuando se incrementa? – AJPennster

+1

'01111111111111111111111111111111' ->' 10000000000000000000000000000000'. Con [complemento de dos] (https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement), el segundo número es negativo. – jterrace

+0

entonces, 10000000000000000000000000000000 es equivalente a -2147483648, ¿correcto? – AJPennster

3

Si un desbordamientos de adición de número entero, entonces el resultado es los bits de orden inferior de la suma matemática como se representa en algunos suficientemente grande formato en complemento a dos. Si se produce el desbordamiento , el signo del resultado es que no es lo mismo que el signo de la suma matemática de los valores de los dos operandos .

http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#13510

5

Como jterrace dice, el de Java en tiempo de ejecución se "envoltura' el resultado a la Integer.MIN_VALUE de -2147483648.

Pero eso es matemáticamente incorrecta! La respuesta correcta Matemáticamente es 2147483648. sin embargo, un 'int' no puede tener un valor de 2147483648. Las fronteras 'int' son -2147483648 a 2147483647

¿Por qué no hace una excepción de Java? ¡Buena pregunta! Un objeto Array lo haría.

Pero los autores del lenguaje conocen el alcance de sus tipos primitivos, por lo que utilizan la técnica de "envoltura" para evitar una excepción costosa.

Usted, como desarrollador, debe probar estos límites de tipo. Una prueba simple para incrementar sería

if(x++ == Integer.MIN_VALUE) 
    //boundary exceeded 

Una prueba simple para decremento habría

if(x-- == Integer.MAX_VALUE) 
    //boundary exceeded 

una prueba completa para ambos sería

if(x++ == Integer.MIN_VALUE || x-- == Integer.MAX_VALUE) 
    //boundary exceeded 
+6

En el último ejemplo, creo que no se pueden usar los operadores ++ y - de esa manera para verificar los límites ya que en realidad están cambiando el valor de x. En su lugar, debería refactorizarse a algo como si (x + 1 == Integer.MIN_VALUE || x - 1 == Integer.MAX_VALUE) – ronkot

4

Lo que pasa es un bit adicional es agregado al bit más a la derecha y la orden disminuye como un int. firmado negativamente ... Observe lo que sucede después de '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); 
0

Esta es una respuesta alternativa por lo que todavía puede seguir siendo básicamente infinito. recomiendo un caso (int> nearmax) a continuación, pasar a new int Ejemplo:

int x = 2000000000; 
x++; 
int stacker = 0; 
if (x > 2000000000) 
{ 
int temp = x; 
x = temp - 2000000000 
stacker++; 
} 

entonces usted puede desapilar cuando sea necesario también ...

decir x = 0

x--; 
if (x < 0 && stacker > 0) 
{ 
int temp = x; 
x = 2000000000 + temp;//plus because it's negative 
stacker--; 
} 

esto da 2000000000 x 2000000000 y quiero decir ... usted podría seguir haciendo esto así que ... ya ...

por supuesto que podría ir aún más lejos si quiere usar nega tive números ...

Cuestiones relacionadas