Problema de vários números de Java com números negativos [duplicado]
Recentemente, estou enfrentando o problema abaixo
public class Main {
public static void main(String[] args) throws Exception {
// Your code here!
int i = -2147483648;
int j = i * -1;
System.out.println("j="+j);
}
}
Resultado: -2147483648
IDE online com código: https://paiza.io/projects/e/17lF_6-GltIcyubZv3QoFg?theme=twilight
Mas como funciona de acordo com a lógica que preciso para obter 2147483648 é um resultado certo? Então, como consegui esse número negativo? É por causa do intervalo de inteiros (Integer.MIN_VALUE)? Como consertar este problema?
Respostas
O valor positivo máximo que um int
pode conter está 2147483647
além do qual o valor vai para a outra extremidade (ou seja, começa na extremidade negativa). Você pode entender na seguinte demonstração:
public class Main {
public static void main(String[] args) {
int i = -2147483648;
int j = i * -1;
System.out.println("j=" + j);
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MAX_VALUE + 1);
System.out.println(Integer.MIN_VALUE);
// Some more examples for you to understand this concept better
System.out.println(Integer.MAX_VALUE + 2);
System.out.println(Integer.MAX_VALUE + 3);
}
}
Resultado:
j=-2147483648
2147483647
-2147483648
-2147483648
-2147483647
-2147483646
Depois de -2147483648
ser multiplicado com -1
, torna-se 2147483648
mas uma int
variável não pode conter esse valor positivo muito grande; então, ele começará do lado negativo (ou seja Integer.MIN_VALUE
).
O número 2147483648 não existe. O maior valor de um int é 2147483647, que é 1 menor do que o resultado esperado. A multiplicação causa um estouro, que 'reverte' o número para o menor valor negativo e continua o cálculo a partir daí. (Com outras palavras: 2147483647 + 1 = -2147483648 (menor negativo)) Como o resultado seria apenas 1 sobre o valor máximo, não há ação adicional necessária e o valor int mínimo é retornado.
Se você quiser corrigir esse problema, use 'long' em vez de 'int' para suas variáveis. Você também pode usar classes mais complexas como BigDecimal ou escrever uma função de multiplicação customizada para matrizes de bytes.
Nota: não importa o tipo numérico que você usa, contanto que a memória usada para representar o número seja finita, você pode ter problemas semelhantes. Embora em circunstâncias normais seja improvável, mesmo para um inteiro de 32 bits (int).