Pregunta

System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);

es cierto.

Entiendo que de enteros en Java es de 32 bits y no puede ir por encima de 231-1, pero no puedo entender por qué la adición de 1 a sus MAX_VALUE resultados en MIN_VALUE y no en algún tipo de excepción.No mencionar algo transparente como la conversión a un tipo más grande, como Ruby no.

Es este comportamiento especificado en algún lugar?Puedo confiar en ella?

¿Fue útil?

Solución

Porque el entero se desborda.Cuando se desborda, el siguiente valor es Integer.MIN_VALUE. JLS relevantes

Si una suma de enteros se desborda, entonces el resultado son los bits de orden inferior de la suma matemática representados en algún formato de complemento a dos suficientemente grande.Si se produce un desbordamiento, el signo del resultado no es el mismo que el signo de la suma matemática de los dos valores de operando.

Otros consejos

El entero de almacenamiento obtiene desbordó y que no se indica en ninguna manera, como se indicó en JSL 3ª Ed.:

El built-in entero operadores no indican desbordamiento o subdesbordamiento de alguna manera.Entero de los operadores puede lanzar una NullPointerException si unboxing de conversión (§5.1.8) de una referencia nula es necesario.Aparte de eso, el único entero de los operadores, que puede lanzar una excepción (§11) son la división de enteros operador / (§15.17.2) y el resto entero del operador % (§15.17.3), que arrojan un ArithmeticException si la derecha del operando es igual a cero, y los operadores de incremento / decremento ++(§15.15.1, §15.15.2) y --(§15.14.3, §15.14.2), lo que puede producir una OutOfMemoryError si el boxeo de conversión (§5.1.7) es necesaria y no hay suficiente memoria disponible para realizar la conversión.

Ejemplo en un 4-bits de almacenamiento:

MAX_INT: 0111 (7)
MIN_INT: 1000 (-8)

MAX_INT + 1:

 0111+
 0001
 ----
 1000

Debe comprender cómo se representan los valores enteros en forma binaria y cómo funciona la suma binaria. Java usa una representación llamada complemento a dos, en la que el primer bit del número representa su signo. Siempre que agregue 1 al entero Java más grande, que tiene un signo de bit de 0, entonces su signo de bit se convierte en 1 y el número se vuelve negativo.

Este enlace explica con más detalles: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java

-

La Especificación del lenguaje Java trata este comportamiento aquí: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

Si una suma entera se desborda, entonces el resultado son los bits de orden inferior de la suma matemática representados en algún formato de complemento a dos suficientemente grande. Si se produce un desbordamiento, el signo del resultado no es el mismo que el signo de la suma matemática de los dos valores de operando.

Lo que significa que puede confiar en este comportamiento.

En la mayoría de los procesadores, las instrucciones aritméticas no tienen modo de fallar en un desbordamiento.Establecen una bandera que debe ser revisada.Esa es una instrucción adicional por lo que probablemente sea más lenta.Para que las implementaciones de idiomas sean lo más rápidas posible, los idiomas se especifican con frecuencia para ignorar el error y continuar.Para Java, el comportamiento se especifica en JLS .Para C, el lenguaje no especifica el comportamiento, pero los procesadores modernos se comportarán como Java.

Creo que hay propuestas para bibliotecas Java SE 8 (incómodas) para generar desbordamiento, así como operaciones sin firmar.Un comportamiento, creo que es popular en el mundo DSP, es fijar los valores al máximo, por lo que Integer.MAX_VALUE + 1 == Integer.MAX_VALUE [no Java].

Estoy seguro de que los lenguajes del futuro utilizarán ints de precisión arbitraria, pero no por un tiempo todavía.Requiere un diseño de compilador más caro para ejecutarse rápidamente.

La misma razón por la que la fecha cambia cuando cruza la línea de fecha internacional: hay una discontinuidad allí.Está integrado en la naturaleza de la suma binaria.

Este es un problema bien conocido relacionado con el hecho de que los números enteros se representan como complemento a dos hacia abajo en la capa binaria.Cuando agrega 1 al valor máximo del número de complemento a dos, obtiene el valor mínimo.Honestamente, todos los enteros se comportaban de esta manera antes de que existiera java, y cambiar este comportamiento para el lenguaje Java habría agregado más gastos generales a las matemáticas de enteros y habría confundido a los programadores provenientes de otros lenguajes.

When you add 3 (in binary 11) to 1 (in binary 1), you must change to 0 (in binary 0) all binary 1 starting from the right, until you got 0, which you should change to 1. Integer.MAX_VALUE has all places filled up with 1 so there remain only 0s.

Cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483647, -2147483646, -2147483645, ... and so forth to the far most right again and on and on, its nature of summing machine on this bit depth.

Some examples:

int a = 2147483647;

System.out.println(a);

gives: 2147483647

System.out.println(a+1);

gives: -2147483648 (cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483648, -2147483647, -2147483646, ... and so fores to the far most right again and on and on, its nature of summing machine on this bit depth)

System.out.println(2-a); 

gives:-2147483645 (-2147483647+2 seems mathematical logical)

System.out.println(-2-a);

gives: 2147483647 (-2147483647-1 -> -2147483648, -2147483648-1 -> 2147483647 some loop described in previous answers)

System.out.println(2*a);

gives: -2 (2147483647+2147483647 -> -2147483648+2147483646 again mathematical logical)

System.out.println(4*a);

gives: -4 (2147483647+2147483647+2147483647+2147483647 -> -2147483648+2147483646+2147483647+2147483647 -> -2-2 (according to last answer) -> -4)`

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top