2012-03-15 13 views
9

Widziałem posty który wyjaśnia bardzo wiele na to pytanie, ale wszystkie wartości stosowane całkowite i szczerze mówiąc nie do końca rozumiem to stąd to pytanie:Generowanie losowego podwójną liczbę pewnym zakresie w Javie

próbuję generowanie liczb losowych z zakresu (-1554900.101) do (52952058699.3098) w języku Java i zastanawiałem się, czy ktoś mógłby mi to wyjaśnić, ponieważ naprawdę chcę to zrozumieć.

Moje przemyślenia: Czy to będzie właściwe podejście? 1) Wygeneruj losową liczbę całkowitą w obrębie podanego zakresu 2) Podziel wygenerowaną liczbę przez pi, aby uzyskać dane zmiennopozycyjne/podwójne losowe wyniki:

Z góry dziękuję.

+1

Naprawdę chcę poznać powody tych precyzyjnych ograniczeń :) – adelphus

+0

W języku Java 7 istnieje prostsza odpowiedź tutaj: http://stackoverflow.com/a/32808589/1743880. – Tunaki

Odpowiedz

34

Oto pomysł. Chcesz losową liczbę w zakresie zakresu, powiedzmy [-1.1,2.2], aby rozpocząć od prostego przykładu. Ten zakres ma długość 3.3 od 2.2 - (-1.1) = 3.3. Teraz większość funkcji "losowych" zwraca liczbę z zakresu [0,1), która ma długość jeden, więc musimy do skalować naszą losową liczbę do naszego pożądanego zakresu.

Random random = new Random(); 
double rand = random.nextDouble(); 
double scaled = rand * 3.3; 

Teraz nasza liczba losowa ma wielkość chcemy, ale musimy przesunąć go na osi liczbowej się między dokładnych wartości chcemy. W tym kroku wystarczy dodać dolną granicę całego zakresu do naszej skalowanej liczby losowej, a my skończymy!

double shifted = scaled + (-1.1); 

Więc teraz możemy umieścić te części razem w jednej funkcji:

protected static Random random = new Random(); 
public static double randomInRange(double min, double max) { 
    double range = max - min; 
    double scaled = random.nextDouble() * range; 
    double shifted = scaled + min; 
    return shifted; // == (rand.nextDouble() * (max-min)) + min; 
} 

Oczywiście, ta funkcja wymaga pewnych sprawdzanie błędów nieoczekiwanych wartości jak NaN ale ta odpowiedź powinna zilustrować ogólną ideę.

+0

Jeśli używam 'Double.MAX_VALUE' vs' Double.MIN_VALUE', to nie linia 3 w twoim ostatni fragment wykracza poza zasięg? – SOFe

7
double lower = -1554900.101; 
double upper = 52952058699.3098; 
double result = Math.random() * (upper - lower) + lower; 
+0

Ale OP szuka * wyjaśnienia *, a nie tłumaczenia z 'int' na' podwójne' typów ... – maerics

2

To powinno być coś takiego:

double rnd = Math.random(); 

double result = ((long)(rnd * (529520586993098L - (-15549001010L) + 1)) -15549001010L)/10000.0; 

+ 1 będzie zrównoważyć fakt, że zakres jest [0;1[ więc górny zakres jest wykluczone.

Najpierw spróbuj znaleźć „całkowitą” (bardzo długo) zakres i dodamy 1, aby zrównoważyć fakt, że ostatnia liczba jest wykluczone, więc 529520586993098L + 15549001010L + 1, a następnie mnożymy ją przez rnd, oddanych do long i odejmować 15549001010L aby przesunąć go z powrotem i na koniec podzielić go przez 10000.0, aby znalazł się w prawym "zakresie".

Jest to prawdopodobnie bardziej jasne:

long range = 529520586993098L + 15549001010L + 1; 

double temp = rnd * range; 
long temp2 = (long)temp; 
temp2 -= 15549001010L; 

double result = temp2/10000.0; 
2

nie jak chciałbym to zrobić.

  • Wygeneruj losowe podwójne. Efektem jest między 0 i 1.
  • pomnożymy tę liczbę przez (HighLimit - LowLimit) (52952058699.3098 - -1.554.900,101)
  • Dodaj LowLimit (random + -1554900.101)

Tutaj jesteś. Masz losową liczbę pomiędzy dolnym a górnym limitem.

1

Random.nextDouble zwraca double w przedziale [0, 1 [więc używać, że mnożą się swoim rozmiarem Range (52952058699,3098 + 1554900.101), a następnie przesunięcie wynik (odejmować 1554900.101), aby uzyskać numer.

Nie wiem, jak bardzo jest to potrzebne, ale bez dalszej analizy można uzyskać liczby poza zakresem, z uwagi na sposób obsługi podwójnych.

Powiązane problemy