Domanda

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

è vero.

Capisco che il numero intero in Java è a 32 bit e non può andare oltre 2 31 -1, ma non riesco a capire perché l'aggiunta di 1 al suo MAX_VALUE risulta in MIN_VALUE e non in qualche tipod'eccezione.Senza menzionare qualcosa come la conversione trasparente in un tipo più grande, come fa Ruby.

Questo comportamento è specificato da qualche parte?Posso fare affidamento su di esso?

È stato utile?

Soluzione

Perché il numero intero trabocca.Quando eccede, il valore successivo è Integer.MIN_VALUE. JLS pertinente

Se un'addizione di interi va in overflow, il risultato sono i bit di ordine inferiore della somma matematica rappresentati in un formato con complemento a due sufficientemente grande.Se si verifica un overflow, il segno del risultato non è lo stesso del segno della somma matematica dei due valori dell'operando.

Altri suggerimenti

Lo spazio di archiviazione intero viene sovraccaricato e ciò non è indicato in ogni modo, come affermato in JSL 3a Ed. :

Gli operatori interi incorporati non indicano in alcun modo overflow o underflow. Gli operatori interi possono lanciare un NullPointerException se la conversione unboxing (§5.1. 8) di un riferimento nullo è obbligatorio. Oltre a questo, gli unici operatori interi che possono generare un'eccezione (§11) sono l'operatore di divisione intero / (§15.17.2) e l'operatore di resto intero % (§15.17.3) , che lancia un ArithmeticException se l'operando di destra è zero, e gli operatori di incremento e decremento ++ ( §15.15.1 , §15.15.2 ) e -- ( §15. 14.3 , §15.14.2 ), che può generare un OutOfMemoryError se la conversione di boxe (§ 5.1.7) è necessario e la memoria disponibile non è sufficiente per eseguire la conversione.

Esempio in una memoria a 4 bit:

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

MAX_INT + 1:

 0111+
 0001
 ----
 1000

Devi capire come vengono rappresentati i valori interi in forma binaria e come funziona l'addizione binaria. Java utilizza una rappresentazione chiamata complemento a due, in cui il primo bit del numero rappresenta il suo segno. Ogni volta che aggiungi 1 al java Integer più grande, che ha un segno di bit pari a 0, il suo segno di bit diventa 1 e il numero diventa negativo.

Questo link spiega con maggiori dettagli: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java

-

La specifica del linguaggio Java tratta questo comportamento qui: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

Se un'addizione di interi va in overflow, il risultato sono i bit di ordine inferiore della somma matematica rappresentati in un formato con complemento a due sufficientemente grande. Se si verifica un overflow, il segno del risultato non è lo stesso del segno della somma matematica dei due valori dell'operando.

Il che significa che puoi fare affidamento su questo comportamento.

Sulla maggior parte dei processori, le istruzioni aritmetiche non hanno alcuna modalità di errore in caso di overflow.Impostano una bandiera che deve essere controllata.Questa è un'istruzione extra quindi probabilmente più lenta.Affinché le implementazioni del linguaggio siano il più veloci possibile, le lingue vengono spesso specificate per ignorare l'errore e continuare.Per Java il comportamento è specificato nel JLS .Per C, il linguaggio non specifica il comportamento, ma i processori moderni si comporteranno come Java.

Credo che ci siano proposte per (imbarazzanti) librerie Java SE 8 da lanciare in caso di overflow, così come operazioni non firmate.Un comportamento, credo popolare nel mondo DSP, è quello di bloccare i valori al massimo, quindi Integer.MAX_VALUE + 1 == Integer.MAX_VALUE [non Java].

Sono sicuro che i linguaggi futuri useranno int di precisione arbitraria, ma non ancora per un po '.Richiede un design del compilatore più costoso per essere eseguito rapidamente.

Lo stesso motivo per cui la data cambia quando si oltrepassa la linea della data internazionale: c'è una discontinuità lì.È integrato nella natura dell'addizione binaria.

Questo è un problema ben noto correlato al fatto che i numeri interi sono rappresentati come complemento a due al livello binario.Quando aggiungi 1 al valore massimo del numero di complemento a due, ottieni il valore minimo.Onestamente, tutti gli interi si comportavano in questo modo prima che esistesse java e la modifica di questo comportamento per il linguaggio Java avrebbe aggiunto più overhead alla matematica dei numeri interi e confusi programmatori provenienti da altri linguaggi.

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)`

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top