Salta al contenuto principale
  1. Blog/

JAVA ed i numeri positivi casuali

··2 minuti

Oggi stavo revisionando del codice JAVA che conteneva una funzione per generare dei Long casuali positivi scritta come segue:

public Long randomPositiveLong() {
    return Math.abs(new Random().nextLong());
}

Riuscite a vedere il BUG nascosto tra le righe?

Il problema di questa funzione si verifica esattamente quando si cerca di rendere positivo il valore Long.MIN_VALUE. Perchè?

Se prendiamo la documentazione ufficiale e andiamo a vedere quali sono i valori che è possibile rappresentare troveremo che Long.MIN_VALUE è uguale a 2-63, mentre Long.MAX_VALUE è uguale a 263-1 (questo perchè tra i numeri positivi c’è anche lo zero). Ciò significa che Long.MIN_VALUE non ha una controparte positiva; nella pratica quel che succede è che Math.abs ritornerà nuovamente il numero come negativo. Questo è anche indicato nella relativa JavaDoc:

Note that if the argument is equal to the value of Long.MIN_VALUE, the most negative representable long value, the result is that same value, which is negative.

Ci sono più modi per riscrivere la funzione, io ho preferito non reinventare la ruota e ho sfruttato la funzione nextLong(long n) che ritorna un Long tra 0 (incluso) ed n (escluso). Questa funzione si trova in una classe un po’ meno conosciuta: ThreadLocalRandom, che è anche pensata per essere usata in ambienti concorrenti. Bene! Due piccioni con una fava!

La funzione riscritta è la seguente

public Long randomPositiveLong() {
    return ThreadLocalRandom.current().nextLong(Long.MAX_VALUE);
}

Come al solito i BUG peggiori si annidano sempre in aree del codice innocue all’apparenza!