Può Java funzione random essere zero?

Per curiosità, può di per la Matematica.random() mai essere zero?

Per esempio, se dovessi avere:

while (true){
  if (Math.random() == 0)
    return 1;
}

Avrei mai effettivamente ottenere un ritorno di uno? C’è anche un errore di arrotondamento da considerare in quanto la Matematica.random() restituisce un valore double.

Chiedo perché il mio CS professore ha dichiarato che random() va da 0 a 1 inclusive, e ho sempre pensato che fosse esclusiva.

  • Era il CS professore parlando di Java, o piuttosto su un matematiche, la funzione casuale con distribuzione uniforme? Perché tale funzione, per i numeri reali nell’intervallo da 0 a 1, non hanno alcuna probabilità di 0. Anche non per 1. Né per 0,5: Una probabilità può essere assegnato solo ad un intervallo. Ma, naturalmente, non vale per un discreto numero di gamma come abbiamo qui in Java… (sono sicuro che quello che voleva dire 😉
  • Basta consultare la documentazione per la Matematica.random(), indicare se è inclusiva o esclusiva.
  • Nessun errore di arrotondamento qui. Ti basta avere un double con 53 uniformemente distribuiti in modo pseudo-casuale di bit nella sua mantissa.
  • Questo post ha pubblicato sulla YT video riguardo un bug di Minecraft: youtube.com/watch?v=JFHGiv6qeX8
  • Penso che ho avuto zero una volta. Stavo scrivendo uno script per spostare un array di cerchi intorno ad un casuale velocità e uno è capitato di essere stazionaria tra il caos circostante
InformationsquelleAutor ThirdD3gree | 2010-06-17



10 Replies
  1. 21

    Secondo la documentazione, “Restituisce un valore double con un segno positivo, maggiore o uguale a 0.0 e inferiore a 1,0.” Questo significa che può essere pari a zero.

    Come Hank ha scritto, è è esclusiva sul limite superiore (non può mai essere 1), quindi, forse, che è dove la confusione deriva da :-).

  2. 38

    Sì, è davvero può essere. Math.random() crea un globale java.util.Random-generatore di semi (System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1) e chiamate nextDouble() per esso. Se il suo seme raggiunge stato 107048004364969L(e lo farà, dal momento che java.util.Random ha tutto il periodo), la prossima double generato sarà 0.0.
    Anche se con la sfortuna si potrebbe finire con il male di parità nel ciclo, perché
    Random.nextDouble() avanza dello stato due volte. Con un po ‘ meno sfortuna si potrebbe avere per generare 2^47 numeri casuali prima che il ciclo termina, come non ho trovato altri semi che danno 0.0.

    Il seme avanza come se da seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
    e doppie sono generati usando il 26 e 27 bit superiori di due volte consecutive valori di inizializzazione. Nell’esempio i due valori di inizializzazione sarà 0L e 11L.

    Se si riesce a creare globale generatore con System.currentTimeMillis()==107038380838084L, il codice restituisce immediatamente. È possibile simulare con:

    java.util.Random k = new java.util.Random(107038380838084L);
    System.out.println(k.nextDouble()==0);

    • E, se si guarda troppo sospetti per colpire zero nella prossima prova, utilizzare new java.util.Random(164311266871034L), e ti ha colpito in due tentativi. O new java.util.Random(240144965573432L), e tre tentativi. O new java.util.Random(881498), e si otterrà uno zero dopo 376050 chiamate a nextDouble.
    • Questo dovrebbe essere accettato risposta. La domanda chiede di java Math.random che (quando prima chiamata) crea un nuovo singolo pseudocasuali-generatore di numero, esattamente come se l’espressione new java.util.Random(), che a sua volta è utilizzato come Random.nextDouble() successivamente, per tutte le chiamate a Math.random(). nextDouble() opere come: return (((long)next(26) << 27) + next(27)) / (double)(1L << 53); (e in modo non corretto nelle prime versioni di java: return (((long)next(27) << 27) + next(27)) / (double)(1L << 54);). Qui next restituisce la richiesta di primo livello di bit (int)(seed >>> (48 - bits)).
    • Se qualcuno vuole provare questo, eseguire il programma su 29.11.5361 alle 3:33:58.084. Ci vuole solo un po ‘ di attesa. In realtà, mi chiedo come molti programmi di fare qualcosa di inaspettato in quel giorno. E ‘ come il 2038 problema. Tranne che dubito fortemente che System.currentTimeMillis verrà usata ancora nella sua forma attuale in 5361.
  3. 10

    È perfettamente possibile che non tornerà mai più esattamente a zero. Java incluso PRNG è a 48-bit LCG, da cui solo 32 bit vengono mai utilizzati. Per tutte le 53 bit di un double mantissa a zero, sarete in sostanza bisogno di almeno uno chiamata a next() dove la parte superiore a 32 bit è zero e un altro in cui la maggior parte di loro sono. (Se non mi sbaglio, direi che questo non potrà mai accadere con come il generatore funziona, ma è tardi, sono stanco, e non voglio puntare molto su di esso.)

    Dal momento che il metodo documentazione esplicitamente come i numeri casuali sono ottenuti c’è anche un po ‘ di margine per le altre implementazioni di Java runtime per produrre risultati diversi. Il contratto potrebbe dire che il numero che si ottiene è da [0, 1). Ma in pratica ci sono un certo numero di valori mai colpito (perché avete bisogno di due valori successivi da un generatore, che foribly produce una dipendenza lineare tra i valori successivi – ci sono solo 48 bit di stato. Non si possono creare tutti diversi, 53-bit combinazioni che – almeno non come è fatto.).

    Naturalmente, poiché Math.random() automaticamente semi statico Random esempio, si potrebbe prendere in considerazione anche il seme qui, che può necessario essere molto specifico per un caso di test a lavorare fuori. E questo potrebbe significare che il punto esatto nel tempo potrebbe essere un paio di decenni o millenni di distanza.

    • Come un pratico controesempio, Angs’ risposta qui sotto mostra una specifica PRNG stato in cui il generatore di tornare esattamente quella combinazione di next()s.
  4. 9

    È comprensivo di zero, esclusiva di uno, ad esempio, [0, 1) o 0 <= x < 1 a seconda notazione che si preferisce.

  5. 5

    In teoria, è possibile restituire il valore zero.

    In pratica, si potrebbe essere necessario attendere un tempo estremamente lungo per ottenere esattamente zero. Se il generatore di numero casuale è implementato bene, non ha almeno 56 bit di stato interno (altrimenti tutti i bit del risultato restituito non essere casuale). E ciò implica che, se la distribuzione dei valori prodotti dall’casuale è piatta, che è almeno una possibilità in 2^56 di tornare un valore di cui tutti i bit sono uguali a zero. Che è circa 10^-19. Io non trattengo il respiro.

    (Altri hanno giustamente osservato che, come documentato, in teoria (e, presumibilmente, in pratica non può restituire il valore 1.0).

    • Si potrebbe fare lo stesso caso per qualsiasi combinazione di 56 bit di stato interno. Se il generatore di numero casuale è implementato bene, la possibilità di ritornare a zero deve essere uguale a qualsiasi altro discreto doppio.
    • D’accordo, ma la domanda era specificamente “può essere zero?”
    • Java utilizza un 48-bit LCG, di cui solo 32 bit sono utilizzati. Questo è anche indicato nella documentazione per nextLong() che semplicemente non di generare tutte le possibili long valori. Lo stesso vale (ovviamente) per doubles.
    • OK, in modo casuale i numeri non sono casuali, come potrebbero essere (32 bit invece di 56). Mi sembra un bello muto attuazione; qual è il punto di un generatore di numeri casuali che non è molto casuale? Ancora solo 1 probabilità su 2^32 o in meno di 1 miliardo di.
    • Le persone sono stati la costruzione di generatori di numeri casuali per decenni; c’era una tonnellata di teoria, quando ho guardato in una algoritmi numerici di classe negli anni ‘ 70. Come costruire una era facilmente disponibile quando Java è venuto fuori. Mi sembra che, semplicemente, ha fatto un pessimo lavoro. Sì, è possibile scrivere il codice del tuo. Il punto di un quadro o di una biblioteca è quello di disporli in modo che non hanno a che fare.
  6. 1

    Matematica.random() è documentato di tornare”, un doppio valore con segno positivo, maggiore o uguale a 0.0 e a meno di 1.0″
    Che è, comprensivi di 0.0, ma esclusiva di 1.0

  7. 1

    è anche possibile, in una conformi JRE attuazione, che NON restituisce 0.

    • è anche possibile, dato un vero generatore casuale e a causa della natura di casualità che, in un conforme JRE attuazione, restituisce SEMPRE 0.
    • Leggi il Javadoc (che, per la libreria standard sono considerati parte integrante del capitolato d’oneri). L’attuazione della Math.random() deve utilizzare java.util.Random che, a sua volta ha una specifica LCG.
    • Ho letto il javadoc, e unita a loro la mia risposta. Il mio punto, in materia di irreputable la risposta è che, se è vero che è possibile che una 0.0 non viene mai restituito è anche possibile che una 0.0 sempre restituito. Per essere a norma deve essere possibile, per qualsiasi valore di x dove 0.0 <= x < 1.0 per essere restituito, tra l’improbabile casi in cui 0 è mai restituito o 0 è sempre restituito. Ho letto irreputable dichiarazione come “si potrebbe scrivere un conforme JRE che vorresti mai tornare a 0.” che è sbagliato, ma il improbabile caso che 0 non è mai restituito corretto.
  8. 1

    È teoricamente possibile per la matematica.random() per restituire un valore pari a zero, ma nel mondo reale, si può contare su di esso, non hanno praticamente mai accadendo.

    Una volta ho eseguito il mio pc per una settimana, in attesa di uno, ha generato circa dieci trilioni di numeri casuali, senza zeri.

    Ma più direttamente, è praticamente esclusiva in entrambi i modi.

    • Non è teoricamente possibile, ma del tutto possibile. Vedere la risposta fornita da @Angs e commenti.
    • L’ho fatto per un mese una volta, non ha mai avuto uno zero.

Lascia un commento