¿Cómo funciona el desbordamiento en java?
integer-overflow (4)
He leído sobre el desbordamiento, sé que "el desbordamiento es cuando un número es tan grande que ya no cabe dentro del tipo de datos, por lo que el sistema se" envuelve "al siguiente valor más bajo y se cuenta a partir de ahí".
Por ejemplo:
short s = (short)1921222; // Stored as 20678
En ese ejemplo, comenzamos a contar desde -32768 (Short.MIN_VALUE)
, pero cuando trato de probar en otros tipos de datos enteros, no parece funcionar de la misma manera ...
byte b = (byte)400; // Stored as -112
El ejemplo anterior comenzó a contar desde 0, que fue la única forma que encontré para obtener -112
No sé si estoy haciendo algo mal.
Además de las otras respuestas, también puede llegar a esa respuesta mediante el cálculo manual.
En Java, el byte
tipo de datos es un entero con signo de 8 bits. Así que los valores están en el intervalo [-128, 127]
. Si tiene un valor de 400
y desea ver el valor real para ese tipo, puede restar el tamaño del intervalo de ese número hasta que alcance un valor que esté dentro del intervalo.
Como dije, el byte
es de 8 bits, por lo que el tamaño del intervalo es de 256
. Resta eso de tu valor inicial: 400 - 256 = 144
. Este valor aún está fuera del intervalo, por lo que debe restar nuevamente: 144 - 256 = -112
. Este valor ahora está dentro del intervalo y, de hecho, es el valor que ha visto en su prueba.
Lo mismo es cierto para su primer ejemplo: short
es de 16 bits y está firmado, por lo que el intervalo es [-32768, 32767]
con un tamaño de 65536
. Hacer una resta repetida del valor 1921222
finalmente le dará el valor 20678
como se ve en su prueba.
El elenco está truncando el número. ( JLS )
0000 0001 1001 0000
pierde el byte alto para convertirse
1001 0000
que es -112.
En java, el tipo de byte
primitivo es un entero con signo de 8 bit
, por eso tienes -112
de llamar:
byte b = (byte) 400;
Puedes evitar eso y obtener su valor sin firmar, añadiéndolo con binario con 0xFF
esta manera:
int b = (byte) 400 & 0xFF;
Para más detalles puedes consultar:
La especificación del lenguaje Java dice:
Los tipos integrales son byte, short, int y long, cuyos valores son enteros de complemento a dos con signo de 8 bits, 16 bits, 32 bits y 64 bits, respectivamente, y char, cuyos valores son enteros sin signo de 16 bits representando unidades de código UTF-16.
Entonces, short
y byte
son los dos enteros del complemento de dos .
short
es de 16 bits, lo que significa que puede contener 2 ^ 16 = 65536 valores diferentes. Después del valor 65536, se desborda.
1921222 modulo 65536 es 20678. Esto es menos de 32768 (2 ^ 15, el punto de inflexión para el complemento de los dos), por lo que mantenemos un número positivo.
byte
es de 8 bits, lo que significa que puede contener 2 ^ 8 = 256 valores diferentes. Este se desborda después del valor de 256hth. 400 módulo 256 es 144. Este valor es mayor que 128, el punto de inflexión para el complemento de los dos, por lo que se interpretará como un número de complemento negativo de dos.