Perché Integer.MAX_VALUE + 1 == Integer.MIN_VALUE?

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

è vero.

Comprendo che l’intero in Java è a 32 bit e non può andare oltre il 2 ^ 31-1, ma non riesco a capire perché aggiungere 1 ai suoi risultati MAX_VALUE in MIN_VALUE e non in qualche tipo di eccezione. Non menzionare qualcosa come la conversione trasparente a un tipo più grande, come fa Ruby.

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

    Perché l’intero trabocca. Quando overflow, il valore successivo è Integer.MIN_VALUE . JLS pertinente

    Se l’aggiunta di un numero intero trabocca, il risultato sono i bit di ordine basso della sum matematica rappresentati in un formato a due complementi sufficientemente grande. Se si verifica un overflow, il segno del risultato non è uguale al segno della sum matematica dei due valori dell’operando.

    L’archivio intero viene sovraccaricato e non è indicato in alcun modo, come indicato in JSL 3 ° Ed. :

    Gli operatori integer integrati non indicano in alcun modo overflow o underflow. Gli operatori di NullPointerException interi possono lanciare una NullPointerException se è richiesta la conversione di unboxing (§5.1.8) di un riferimento null. Oltre a questo, gli unici operatori interi che possono generare un’eccezione (§11) sono l’operatore di divisione dei numeri interi / (§15.17.2) e l’operatore di resto dei numeri interi % (§15.17.3) , che generano un’eccezione ArithmeticException se il diritto l’operando della mano è zero e gli operatori di incremento e decremento ++ ( §15.15.1 , §15.15.2 ) e -- ( §15.14.3 , §15.14.2 ), che possono lanciare un OutOfMemoryError se la conversione di boxe (§5.1 .7) è richiesto e non è disponibile memoria 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 

    Credo che questo link spieghi ciò che stai vedendo: http://en.wikipedia.org/wiki/Two's_complement

    È necessario comprendere in che modo i valori interi sono rappresentati in forma binaria e come funziona l’aggiunta binaria. Java usa una rappresentazione chiamata complemento a due, in cui il primo bit del numero rappresenta il suo segno. Ogni volta che aggiungi 1 al più grande numero intero java, che ha un segno di bit di 0, allora 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 della lingua Java considera questo comportamento qui: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

    Se l’aggiunta di un numero intero trabocca, il risultato sono i bit di ordine basso della sum matematica rappresentati in un formato a due complementi sufficientemente grande. Se si verifica un overflow, il segno del risultato non è uguale al segno della sum matematica dei due valori dell’operando.

    Il che significa che puoi fare affidamento su questo comportamento.

    Lo stesso motivo per cui la data cambia quando si attraversa la linea di data internazionale: c’è una discontinuità lì. È integrato nella natura dell’aggiunta binaria.

    Questo è un problema ben noto legato al fatto che gli interi sono rappresentati come complemento a due a livello binario. Quando aggiungi 1 al valore massimo del numero del complemento a due ottieni il valore minimo. Onestamente, tutti gli interi si sono comportati in questo modo prima che esistesse java e la modifica di questo comportamento per il linguaggio Java avrebbe aggiunto un ulteriore overhead all’intero matem e ai programmatori confusi provenienti da altre lingue.

    Nella maggior parte dei processori, le istruzioni aritmetiche non hanno alcuna modalità di errore su un overflow. Impostano una bandiera che deve essere controllata. Questa è un’istruzione extra, quindi probabilmente più lenta. Affinché l’implementazione della lingua sia il più veloce ansible, le lingue vengono spesso specificate per ignorare l’errore e continuare. Per Java il comportamento è specificato in JLS . Per C, il linguaggio non specifica il comportamento, ma i processori moderni si comporteranno come Java.

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

    Sono certo che le lingue future useranno precisioni arbitrarie, ma non ancora per un po ‘. Richiede un design del compilatore più costoso per essere eseguito rapidamente.

    Quando aggiungi 3 (in binario 11 ) a 1 (in binario 1 ), devi passare a 0 (in binario 0 ) tutto il binario 1 partire da destra, finché non ottieni 0, che dovresti cambiare a 1 . Integer.MAX_VALUE ha tutti i posti pieni di 1 quindi rimangono solo 0 s.