La Multiplication de deux entiers débordant d'entraîner un nombre négatif
Considérer cet extrait de la Java langage de spécification.
class Test {
public static void main(String[] args) {
int i = 1000000;
System.out.println(i * i);
long l = i;
System.out.println(l * l);
}
}
La sortie est
-727379968
1000000000000
Pourquoi le résultat -727379968
pour (i*i)
? Idéalement, il devrait être e 1000000000000.
Je sais que la gamme de nombre Entier est à partir de -2147483648 à 2147483647. alors, évidemment, e 1000000000000
n'est pas dans la plage donnée.
Pourquoi la suite de devenir -727379968
?
Vous devez vous connecter pour publier un commentaire.
Java (comme la plupart des architectures d'ordinateur ces jours-ci) utilise ce qu'on appelle en complément à deux arithmétique, qui utilise le bit de poids fort d'un entier pour signifier qu'un nombre est négatif. Si vous multiplier deux grands nombres, vous vous retrouvez avec un nombre si grand qu'il jeux de bit plus élevé, et le résultat se termine négatif.
Vous pourriez vouloir vérifier Débordement d'entier comme un concept général.
Dépassement de capacité et de dépassement de capacité sont traitées différemment en fonction de la langue, aussi. Voici un article sur Débordement d'entier et de dépassement de capacité en Java.
Que la raison pourquoi il en est ainsi dans le langage Java, comme toujours, c'est un compromis entre la simplicité dans la langue de conception et de performance. Mais dans Java casse-têtes (puzzle 3), les auteurs critiquent le fait que les débordements sont silencieux en Java:
Permet de regarder le binaire:
1000000 est
1111 0100 0010 0100 0000
.E 1000000000000 est
1110 1000 1101 0100 1010 0101 0001 0000 0000 0000
Cependant, les deux premières sections de 4 bits ne rentre pas dans un
int
(depuisint
est de 32 bits de Java,) et donc, ils sont abandonnés, laissant seulement1101 0100 1010 0101 0001 0000 0000 0000
, qui est-727379968
.En d'autres termes, le résultat déborde pour
int
, et vous obtenez ce qui est à gauche.Certains des autres réponses expliquer correctement pourquoi ce qui se passe (c'est à dire. signé deux du compliment de la logique binaire).
De la solution réelle du problème et la façon d'obtenir la bonne réponse en Java lors de l'utilisation vraiment de grands nombres est d'utiliser la classe BigInteger, qui fonctionne également pour les valeurs longues.
Les raisons pour lesquelles integer overflow se produit ont déjà été expliqué dans d'autres réponses.
Un moyen pratique pour assurer la longévité de l'arithmétique dans les calculs est d'utiliser les littéraux numériques avec
l
suffixe qui déclarent les littéraux delong
.Ordinaire entier multiplication qui déborde:
De Multiplication où l'un des multiplicands a
l
suffixe qui n'a pas de dépassement de capacité:Noter que
long
s sont également sujettes à débordement, mais la portée est beaucoup plus grande, de-9,223,372,036,854,775,808
à9,223,372,036,854,775,807
.