Valore massimo di long in Java: Long.MAX_VALUE, intervallo e overflow (con esempi)

目次

1. Qual è il Valore Massimo del Tipo long di Java?

Il valore massimo del tipo long di Java è 9223372036854775807.
È definito come la costante Long.MAX_VALUE.

Confermiamo prima la conclusione.

public class Main {
    public static void main(String[] args) {
        System.out.println(Long.MAX_VALUE);
    }
}

Output:

9223372036854775807

In altre parole, questo è il valore positivo più grande che puoi memorizzare in un long di Java.

1.1 Il Valore Massimo di long È “9223372036854775807”

Questo valore può essere espresso con la seguente formula:

2^63 - 1

Il punto chiave è perché è “63”.

  • Il tipo long è un intero a 64 bit .
  • 1 bit è usato per il segno (positivo/negativo) .
  • I restanti 63 bit rappresentano il valore numerico.

Pertanto,

maximum value = 2^63 - 1

diventa il massimo.

*Un “bit” è l’unità più piccola di dati che rappresenta 0 o 1.

1.2 Perché Non È 2^64 − 1 Anche Se È a 64 Bit?

Questo è il punto che confonde di più i principianti.

Il long di Java è un intero con segno.
“Con segno” significa che può rappresentare sia valori positivi che negativi.

Suddivisione dei 64 bit:

  • 1 bit → segno
  • 63 bit → valore

Quindi il valore positivo più grande è:

2^63 - 1

Ecco perché.

“2^64 – 1” si applica a un intero senza segno.
Java non ha un tipo unsigned long.

⚠ Malinteso comune

  • × Il valore massimo di long è 18446744073709551615
  • ○ Corretto: 9223372036854775807

1.3 Controlla Anche il Valore Minimo di long

Il valore minimo è un altro elemento essenziale da memorizzare insieme al massimo.

System.out.println(Long.MIN_VALUE);

Output:

-9223372036854775808

In forma di formula:

-2^63

Il valore assoluto è 1 più grande del massimo perché Java gestisce gli interi usando il complemento a due.

*Il complemento a due è il meccanismo standard che i computer usano per rappresentare i numeri negativi.

Errori Comuni e Note

  • Confonderlo con 2^64-1
  • Assumere che esista un unsigned long
  • Cercare di memorizzare il valore direttamente e sbagliare le cifre
  • Confonderlo con int (32-bit)

In particolare, confonderlo con il valore massimo di int (2147483647) è estremamente comune.

2. Come Ottenere il Valore Massimo di long in Java

Quando si lavora con il valore massimo di long, la regola è: non scrivere il numero direttamente—usa la costante.
Qui spiegheremo modi sicuri e pratici per ottenerlo.

2.1 Usa Long.MAX_VALUE (Raccomandato)

In Java, il valore massimo è definito nella classe java.lang.Long.

long max = Long.MAX_VALUE;
System.out.println(max);

Output:

9223372036854775807

Perché dovresti usare una costante?

  • Previene errori di cifre/errori di battitura
  • Migliora la leggibilità
  • Rende il tipo esplicito
  • Più robusto ai cambiamenti futuri (i cambiamenti nelle specifiche sono improbabili, ma è più sicuro)

Non è richiesto un import speciale.
Il pacchetto java.lang è importato automaticamente.

2.2 Note Quando Scrivi il Numero Direttamente

Puoi anche scrivere il valore massimo direttamente.

long max = 9223372036854775807L;

La parte importante qui è la “L” finale.

Perché è richiesta la “L”?

In Java, un letterale intero (un letterale numerico) è trattato come un int per impostazione predefinita se non viene aggiunto nulla.

Questo significa:

long max = 9223372036854775807;  // Error

Questo causa un errore di compilazione.

Motivo:

  • Supera l’intervallo di int
  • Non indica esplicitamente che è un long

Corretto:

long max = 9223372036854775807L;

⚠ Una l minuscola è difficile da distinguere dalla cifra 1, quindi si raccomanda la L maiuscola.

2.3 Rischi dell’Hardcoding

“L’hardcoding” significa scrivere il valore numerico direttamente.

Esempio:

if (value == 9223372036854775807L) {
    // Processing
}

Problemi:

  • Il significato non è chiaro
  • Bassa manutenibilità
  • Difficile da capire per altri sviluppatori

Raccomandato:

if (value == Long.MAX_VALUE) {
    // Processing
}

Questo rende chiara l’intenzione del codice.

Errori comuni

  • Dimenticare di aggiungere L e ottenere un errore di compilazione
  • Tentare di assegnarlo a una variabile int
  • Scrivere Long max = Long.MAX_VALUE; e non considerare la gestione potenziale di null (quando si usano classi wrapper)
  • Tentare di calcolarlo con Math.pow(2,63) (diventa double e introduce problemi di precisione)

*Math.pow() restituisce un double, quindi non è adatto per calcoli interi esatti.

3. Cosa succede se un long supera il valore massimo? (Overflow)

Il tipo long può gestire solo un intervallo finito.
Quindi, se superi il valore massimo, non genera un errore—il suo valore si avvolge (cicla).
Questo è chiamato “overflow.”

3.1 Un esempio reale di overflow

Verifichiamolo in pratica.

public class Main {
    public static void main(String[] args) {
        long max = Long.MAX_VALUE;
        long overflow = max + 1;

        System.out.println("Max value: " + max);
        System.out.println("Max value + 1: " + overflow);
    }
}

Output:

Max value: 9223372036854775807
Max value + 1: -9223372036854775808

Puoi vedere che max + 1 diventa il valore minimo.

Questo non è anomalo—è il comportamento definito dalla specifica Java.

3.2 Perché non diventa un errore?

I tipi interi Java (int / long) non lanciano eccezioni quando il valore supera l’intervallo.

Motivo:

  • Numero fisso di bit (long è a 64 bit)
  • I valori si avvolgono a causa della rappresentazione in complemento a due

Concettualmente:

Max value → +1 → Min value
Min value → -1 → Max value

Il computer semplicemente elabora i bit, quindi non ha il concetto di “fuori intervallo”.

⚠ Confusione comune dei principianti

  • Supponendo che “sarà un errore”
  • Il segno cambia improvvisamente e diventa un bug

3.3 Come rilevare l’overflow

Non è possibile rilevarlo con una normale addizione.

Metodo 1: Usa Math.addExact() (Consigliato)

try {
    long result = Math.addExact(Long.MAX_VALUE, 1);
} catch (ArithmeticException e) {
    System.out.println("Overflow occurred");
}

Math.addExact() lancia un ArithmeticException quando il risultato supera l’intervallo.

Ci sono anche:

  • Math.subtractExact()
  • Math.multiplyExact()

anch’essi.

3.4 Come effettuare un controllo di intervallo

Puoi anche controllare prima di aggiungere.

if (value > Long.MAX_VALUE - addValue) {
    System.out.println("Adding will overflow");
}

*In pratica, addExact() è solitamente più sicuro di questo approccio.

3.5 Usa BigInteger (Nessun limite superiore)

Se long non è sufficiente, usa BigInteger.

import java.math.BigInteger;

BigInteger a = new BigInteger("9223372036854775807");
BigInteger b = BigInteger.ONE;
BigInteger result = a.add(b);

System.out.println(result);

BigInteger non ha limite di cifre.

Ma nota:

  • Più lento di long
  • Usa più memoria
  • Non è un tipo primitivo (è un tipo oggetto)

Errori comuni e note

  • Usare long per calcoli monetari e non notare l’overflow
  • Generare ID senza considerare i limiti superiori
  • Usare Math.pow e introdurre errori di precisione
  • Convertire a double e ritorno (perdita di precisione)

Questo può diventare un bug fatale, specialmente nell’elaborazione finanziaria.

4. Confrontare i valori massimi con altri tipi interi

Per comprendere correttamente il valore massimo di long, dovresti anche organizzare come differisce dagli altri tipi interi.
In Java, ogni tipo intero ha un intervallo chiaramente definito basato sulla sua larghezza in bit.

4.1 Differenza da int

int è un intero con segno a 32 bit.

System.out.println(Integer.MAX_VALUE);

Output:

2147483647

Confronto:

TypeBit widthMaximum value
int32-bit2,147,483,647
long64-bit9,223,372,036,854,775,807

Un long può gestire un intervallo circa 4,3 miliardi di volte più grande di un int.

⚠ Errori comuni

  • Supponendo che int sia sufficiente e in seguito causare overflow a causa della crescita
  • Mappare un BIGINT di database a int

4.2 Confronto con short e byte

Controlliamo anche i tipi di interi più piccoli.

System.out.println(Short.MAX_VALUE);  // 32767
System.out.println(Byte.MAX_VALUE);   // 127
TypeBit widthMaximum value
byte8-bit127
short16-bit32767
int32-bit2147483647
long64-bit9223372036854775807

Casi d’uso tipici:

  • byte → casi d’uso per la compressione dei dati
  • short → valori numerici su piccola scala
  • int → elaborazione tipica degli interi
  • long → ID grandi e timestamp

4.3 Quando Dovresti Usare long?

Casi tipici in cui usi long:

  • Timestamp UNIX (millisecondi)
  • Colonne BIGINT del database
  • ID sequenziali grandi
  • Dimensioni dei file (byte)

Esempio:

long timestamp = System.currentTimeMillis();

System.currentTimeMillis() restituisce un long.
Questo perché i valori a livello di millisecondo non entrano in un int.

4.4 Rischi dell’Uso Innecessario di long

Un long usa 8 byte.
Un int usa 4 byte.

Quando si gestiscono grandi quantità di dati:

  • L’uso della memoria aumenta
  • L’efficienza della cache diminuisce
  • Impatto sulle prestazioni (dipende dall’ambiente)

Pertanto,

Se l’intervallo si adatta chiaramente a int, usa int.

è il principio base.

Errori Comuni e Note

  • Il DB è BIGINT ma Java usa int
  • Ricezione di valori numerici JSON come int anche se assumono long
  • Perdita di precisione a causa di cast impliciti durante la conversione di tipo
  • Assegnazione diretta dei risultati di Math.pow a long

I bug dovuti a incongruenze di tipo sono particolarmente comuni nelle integrazioni API.

5. Scenari Pratici per la Gestione del Valore Massimo di long

Il valore massimo di long non è solo conoscenza teorica—è importante nello sviluppo reale.
Capirlo è essenziale, specialmente nei processi in cui l’overflow numerico può diventare fatale.

5.1 Timestamp UNIX

Quando si recupera l’ora corrente in Java:

long now = System.currentTimeMillis();
System.out.println(now);

System.currentTimeMillis() restituisce il numero di millisecondi dal 1 gennaio 1970.

Se lo memorizzi in un int:

int now = (int) System.currentTimeMillis();  // Dangerous

Il valore è corrotto (vengono mantenuti solo i 32 bit inferiori).

⚠ Note

  • Troncatura a causa del cast
  • Il problema dell’anno 2038 (limite dei timestamp basati su int)
  • Confusione tra secondi e millisecondi

Usare long evita il problema dell’anno 2038.

5.2 Integrazione con Database (BIGINT)

In molti database, BIGINT è un intero a 64 bit.

Esempio:

CREATE TABLE users (
    id BIGINT PRIMARY KEY
);

Dalla parte Java:

long id;

Se lo ricevi come un int:

  • Corruzione dei dati
  • Eccezioni quando si raggiunge il limite superiore
  • Nessuna scalabilità futura

⚠ Errori comuni nel mondo reale

  • int è sufficiente all’inizio → cifre insufficienti in seguito
  • Mappatura di tipo errata in ORM
  • Problemi di precisione numerica durante la conversione JSON (JavaScript è sicuro solo fino a 53 bit)

5.3 Generazione di ID e Limiti Superiori

Gli ID distribuiti (ad es., ID in stile Snowflake) usano tipicamente long.

Esempio:

long id = generateId();

Motivi:

  • Lo spazio a 64 bit è sufficientemente grande
  • Sequenza, timestamp e ID macchina possono essere divisi in bit

Tuttavia, teoricamente, long ha anche un limite superiore.

Controllo di esempio:

if (currentId == Long.MAX_VALUE) {
    throw new IllegalStateException("ID upper limit reached");
}

In pratica, questo viene raggiunto raramente, ma dovrebbe essere considerato nella progettazione del sistema.

5.4 Calcoli delle Dimensioni dei File

Ottenere la dimensione di un file:

File file = new File("example.txt");
long size = file.length();

Per file grandi, int non è sufficiente.

⚠ Note

  • Non convertire long in int
  • Gli indici degli array sono int (è qui che si verificano le limitazioni)

Errori Comuni nel Mondo Reale

  • Perdita di precisione in JavaScript quando si gestisce long in JSON
  • Non aggiornare il codice Java quando si cambiano i tipi di colonna del DB
  • Usare long per calcoli monetari e causare overflow
  • Progettare ID persistenti senza considerare i limiti superiori

6. Convinzioni Erronee Comuni sul Valore Massimo di long

Il valore massimo di long è un argomento con molti fraintendimenti nei risultati di ricerca.
Qui organizziamo i punti più confusi.

6.1 Non esiste unsigned long in Java

Questo è particolarmente confuso per gli sviluppatori con esperienza in C/C++.

Java non ha:

an unsigned long type

Un long è sempre un intero con segno a 64 bit.

Pertanto, il valore positivo massimo è:

2^63 - 1

Questo è il limite.

Dal Java 8, sono stati aggiunti i seguenti metodi:

Long.compareUnsigned(a, b);
Long.divideUnsigned(a, b);

Tuttavia, questi sono metodi di supporto per operazioni unsigned—non esiste ancora un tipo unsigned long.

6.2 Il valore massimo non è 2^64 − 1

Disinformazione spesso trovata online:

18446744073709551615

Questo è il valore massimo di un intero unsigned a 64 bit.

Poiché il long di Java è signed:

The maximum value is 9223372036854775807

Questo è il valore corretto.

Riepilogo della differenza:

TypeMaximum value
Signed 64-bit2^63 – 1
Unsigned 64-bit2^64 – 1

Java utilizza il primo.

6.3 BigInteger e long sono diversi

BigInteger rappresenta interi con praticamente nessun limite superiore.

Differenza:

TypeUpper limitNature
longFixed 64-bitPrimitive type
BigIntegerVirtually unlimitedObject type

BigInteger:

  • Usa più memoria
  • Calcoli più lenti
  • Richiede equals() per il confronto

long:

  • Veloce
  • Leggero
  • Intervallo fisso

Scegli in base al tuo caso d’uso.

6.4 È pericoloso calcolare il massimo con Math.pow

Esempio errato:

long max = (long) Math.pow(2, 63) - 1;

Problemi:

  • Math.pow restituisce un double
  • double ha precisione a 53 bit
  • Si verificano errori di precisione per interi grandi

Approccio corretto:

long max = Long.MAX_VALUE;

Riepilogo delle confusioni comuni

  • Pensare che esista unsigned long
  • Confondere con 2^64 – 1
  • Tentare di calcolarlo con Math.pow
  • Distruggere la precisione tramite conversione a double
  • Confondere BigInteger con long

7. Riepilogo (Revisione rapida)

Ecco un riepilogo conciso dei punti chiave di cui hai bisogno in pratica.

7.1 Risposta finale: valore massimo di long

  • Valore massimo: 9223372036854775807
  • Costante: Long.MAX_VALUE
  • Formula: 2^63 – 1
  • Tipo: intero con segno a 64 bit

Codice di verifica:

System.out.println(Long.MAX_VALUE);

7.2 Regole essenziali da seguire

  • Non codificare in modo hardcoded il valore numerico massimo—usa Long.MAX_VALUE
  • Aggiungi L quando scrivi un literal long
  • Non confonderlo con int
  • L’overflow non genera automaticamente un’eccezione

7.3 Come prevenire l’overflow

Per sommare in modo sicuro:

Math.addExact(a, b);

Se il valore può superare il limite:

  • Usa BigInteger
  • Implementa controlli di intervallo

7.4 Punti importanti in pratica

  • Ricevi i valori DB BIGINT come long
  • Usa long per i timestamp UNIX
  • Fai attenzione alla precisione nelle integrazioni JSON
  • Considera i limiti superiori quando progetti sistemi di ID

7.5 Checklist più importante

  • Stai usando erroneamente 2^64 – 1?
  • Supponi che esista unsigned long?
  • Lo stai calcolando con Math.pow?
  • Stai castando long a int?
  • Capisci cosa succede in caso di overflow?

Il valore massimo di long non è solo qualcosa da memorizzare—è un concetto fondamentale che influisce sulla tua comprensione dei tipi interi nel loro complesso.

FAQ

Q1. Qual è il valore massimo del long di Java?

9223372036854775807.
Puoi ottenerlo con Long.MAX_VALUE.

Q2. Quanti bit ha un long?

È un intero con segno a 64 bit.
1 bit è per il segno, e i restanti 63 bit rappresentano il valore.

Q3. Cosa succede se superi Long.MAX_VALUE?

Non si verifica alcun errore.
Si avvolge al valore minimo (-9223372036854775808).

System.out.println(Long.MAX_VALUE + 1);

Q4. Java ha unsigned long?

No, non come tipo.
Java 8 e versioni successive forniscono metodi di supporto per operazioni unsigned, ma il tipo è sempre signed.

Q5. Esiste un modo sicuro per calcolare il valore massimo?

Non calcolarlo direttamente. Usa sempre:

Long.MAX_VALUE

Math.pow() restituisce un double e quindi è impreciso per interi grandi.

Q6. Devo usare int o long?

  • Se l’intervallo è entro circa 2,1 miliardi → usa int
  • Se può superarlo → usa long

Usa long per le colonne DB BIGINT e per i timestamp.

Q7. Quante cifre può gestire long?

Il valore massimo ha 19 cifre:
9223372036854775807

Q8. Qual è la differenza tra long e BigInteger?

  • long → 64-bit fisso, veloce
  • BigInteger → praticamente illimitato, più lento

Se l’intervallo rientra in long, usare long è l’approccio standard.