Per un po 'di contesto:
Qualche tempo fa ho pienamente analizzato questa implementazione. Ho trovato alcune differenze.
A il primo (perfettamente fine) è un diverso valore grande (MBIG
). Numerical Recipies afferma che Knuth chiarisce che qualsiasi grande valore dovrebbe funzionare, quindi non è un problema, e Microsoft ha ragionevolmente scelto di utilizzare il valore più grande di un intero a 32 bit.
La seconda era quella costante, hai menzionato. Quello è un grosso problema. Nel minimo diminuirà sostanzialmente il periodo. Ci sono state segnalazioni che gli effetti sono in realtà peggiori di così.
Ma poi arriva un'altra differenza particolarmente sgradevole. Si è letteralmente garantito di polarizzare l'output (poiché lo fa direttamente), e probabilmente influenzerà anche il periodo del RNG.
Quindi, qual è questo secondo problema? Quando .NET è uscito per la prima volta, Microsoft non si è resa conto che l'RNG che codificava era inclusivo alle due estremità e lo hanno documentato come esclusivo alla fine massima. Per risolvere il problema, il team addetto alla sicurezza ha aggiunto una riga di codice piuttosto malvagia: if (retVal == MBIG) retVal--;
. Questo è molto sfortunatamente dato che la correzione corretta sarebbe letteralmente solo 4 caratteri aggiunti (più spazi bianchi).
la correttezza correzione sarebbe stata cambiare MBIG
-int.MaxValue-1
, ma passa Sample()
utilizzare MBIG+1
(vale a dire continuare a utilizzare int.MaxValue
). Ciò garantirebbe che quel Campione abbia il range [0.0, 1.0) senza introdurre alcun bias, e cambia solo il valore di MBIG
che le Ricette Numeriche hanno detto che Knuth ha detto che è perfettamente a posto.
fonte
2015-08-10 17:30:35
Dov'è @EricLippert se hai bisogno di lui? –
* Tuttavia, nell'implementazione .NET questo campo è impostato sul valore 21. Perché? * Hanno appena scelto un numero casuale;) –
Inoltre, c'è un MZ costante che non viene utilizzato affatto, invece il valore '0' è semplicemente usato in quei posti. –