Prosta odpowiedź na Twoje pytanie brzmi: Math.random()
narusza zasadę nr 2.
Wiele innych odpowiedzi tutaj wskazywało, że obecność Math.random()
oznacza, że ta funkcja nie jest czysta. Ale myślę, że warto powiedzieć, dlaczego Math.random()
skazi funkcje, które go używają.
Podobnie jak wszystkie generatory liczb pseudolosowych, Math.random()
zaczyna się od wartości „ziarna”. Następnie używa tej wartości jako punktu wyjścia dla łańcucha niskopoziomowych manipulacji bitami lub innych operacji, które powodują nieprzewidywalne (ale nie w rzeczywistości losowe ) dane wyjściowe.
W JavaScript zaangażowany proces jest zależny od implementacji i w przeciwieństwie do wielu innych języków JavaScript nie zapewnia możliwości wyboru ziarna :
Implementacja wybiera początkowe ziarno do algorytmu generowania liczb losowych; nie może być wybrany ani zresetowany przez użytkownika.
Dlatego ta funkcja nie jest czysta: JavaScript zasadniczo używa niejawnego parametru funkcji, nad którym nie masz kontroli. Odczytuje ten parametr z danych obliczonych i przechowywanych w innym miejscu, a zatem narusza zasadę nr 2 w Twojej definicji.
Jeśli chcesz, aby była to czysta funkcja, możesz użyć jednego z alternatywnych generatorów liczb losowych opisanych tutaj . Zadzwoń do tego generatora seedable_random
. Pobiera jeden parametr (ziarno) i zwraca „losową” liczbę. Oczywiście ta liczba wcale nie jest przypadkowa; jest wyjątkowo określona przez nasienie. Dlatego jest to czysta funkcja. Wynik seedable_random
jest tylko „losowy” w tym sensie, że przewidywanie wyniku na podstawie danych wejściowych jest trudne.
Czysta wersja tej funkcji musiałaby mieć trzy parametry:
function test(min, max, seed) {
return seedable_random(seed) * (max - min) + min;
}
Dla dowolnej potrójnej (min, max, seed)
wartości zawsze zwróci to ten sam wynik.
Zwróć uwagę, że jeśli chcesz, aby wynik seedable_random
był naprawdę losowy, musisz znaleźć sposób na losowanie ziarna! I jakakolwiek strategia, której użyłeś, nieuchronnie nie byłaby czysta, ponieważ wymagałaby od ciebie zebrania informacji ze źródła spoza twojej funkcji. Jak przypominają mi mtraceur i jpmc26 , obejmuje to wszystkie podejścia fizyczne: sprzętowe generatory liczb losowych , kamery internetowe z osłonami obiektywów , kolektory szumów atmosferycznych - nawet lampy lawowe . Wszystko to wiąże się z wykorzystaniem danych obliczonych i przechowywanych poza funkcją.
Math.random()
co zmienia stan RNG.