Wyjaśnienie Math.random ()

133

To jest całkiem proste pytanie dotyczące języka Java (choć prawdopodobnie ma zastosowanie do każdego programowania):

Math.random() zwraca liczbę od zera do jednego.

Jeśli chcę zwrócić liczbę całkowitą od zera do setki, zrobiłbym:

(int) Math.floor(Math.random() * 101)

Pomiędzy stu a stu zrobiłbym:

(int) Math.ceil(Math.random() * 100)

Ale co jeśli chciałbym uzyskać liczbę od trzech do pięciu? Czy będzie to takie stwierdzenie:

(int) Math.random() * 5 + 3

Wiem o nextInt()w java.lang.util.Random. Ale chcę się nauczyć, jak to zrobić Math.random().

switz
źródło
Na [3,5]:(int)Math.floor(Math.random()*3) + 3
good_evening
9
Przy okazji: zakres wynosi od 0,0 włącznie do 1,0 wyłącznego (nie uzyskasz nigdy 1.0). Korzystanie z nextInt () jest znacznie lepszym wyborem, nie tylko jest prostsze, ale także znacznie szybsze.
Peter Lawrey
2
Korzystanie Math.ceiljest źle, to daje zły wynik, gdy Math.random()powróci 0.
starblue
Co się stanie, jeśli Math.floor zwróci wartość 0,029? Jak zawsze uzyskać dwucyfrową liczbę za pomocą jednego wyciągu?
Naisheel Verdhan

Odpowiedzi:

165
int randomWithRange(int min, int max)
{
   int range = (max - min) + 1;     
   return (int)(Math.random() * range) + min;
}

Wyjście randomWithRange(2, 5)10 razy:

5
2
3
3
2
4
4
4
5
4

Granice są włącznie, tj. [2,5] i minmuszą być mniejsze niż maxw powyższym przykładzie.

EDIT: Jeśli ktoś zamierza spróbować i być głupi i do tyłu mini max, można zmienić kod do:

int randomWithRange(int min, int max)
{
   int range = Math.abs(max - min) + 1;     
   return (int)(Math.random() * range) + (min <= max ? min : max);
}

EDIT2: W przypadku pytania dotyczącego doubles to po prostu:

double randomWithRange(double min, double max)
{
   double range = (max - min);     
   return (Math.random() * range) + min;
}

I znowu, jeśli chcesz to udowodnić idiotom, po prostu:

double randomWithRange(double min, double max)
{
   double range = Math.abs(max - min);     
   return (Math.random() * range) + (min <= max ? min : max);
}
AusCBloke
źródło
1
Co jeśli nie używasz (int)i chcesz, aby zwracała double?
switz
Jeśli chcesz podwoić, po prostu zamień ints na doubles (a rzutowanie typu jest niepotrzebne). Zakładałem, że chcesz, intale dodam do mojego postu.
AusCBloke
2
Właściwie za pomocą doubles usuń + 1również, ponieważ Math.random()nie jest obcięty. Jednak zakres będzie wynosił [min, max), ponieważ Math.random„Zwraca podwójną wartość ze znakiem dodatnim, większą lub równą 0,0 i mniejszą niż 1,0”. maxPrawdopodobieństwo, że liczba i tak będzie dokładnie taka sama, jak i tak byłaby minimalne, nawet gdyby było to możliwe.
AusCBloke
44

Jeśli chcesz wygenerować liczbę od 0 do 100, Twój kod będzie wyglądał następująco:

(int)(Math.random() * 101);

Aby wygenerować liczbę od 10 do 20:

(int)(Math.random() * 11 + 10);

W ogólnym przypadku:

(int)(Math.random() * ((upperbound - lowerbound) + 1) + lowerbound);

(gdzie lowerboundjest włączający i upperboundwyłączny).

Włączenie lub wyłączenie upperboundzależy od Twojego wyboru. Powiedzmy, że range = (upperbound - lowerbound) + 1wtedy upperboundjest włączający, ale jeśli range = (upperbound - lowerbound)to upperboundjest wyłączny.

Przykład: Jeśli chcę liczbę całkowitą między 3-5, to jeśli zakres wynosi (5-3) +1, to 5 jest włącznie, ale jeśli zakres wynosi tylko (5-3), to 5 jest wyłączne.

Teezy7
źródło
2
upperboundEkskluzywny? Myślę, że będzie to obejmujące.
vidit,
1
@vidit to ekskluzywne
1
nie myśl, że dostaniesz duży obraz
górna granica
19

RandomKlasa Java znajduje się w java.utilpakiecie będzie służyć swój cel lepiej. Ma kilka nextInt()metod, które zwracają liczbę całkowitą. Ten, który przyjmuje argument int, wygeneruje liczbę od 0 do tego int, druga nie jest włącznie.

G_H
źródło
Zaktualizowałem moje pytanie, chciałbym wiedzieć, jak to zrobić Math.random(). Dzięki.
switz
1

Aby wygenerować liczbę od 10 do 20 włącznie, możesz użyć java.util.Random

int myNumber = new Random().nextInt(11) + 10
Ilya Gazman
źródło
0

Oto metoda, która przyjmuje granice i zwraca losową liczbę całkowitą. Jest nieco bardziej zaawansowany (całkowicie uniwersalny): granice mogą być zarówno dodatnie, jak i ujemne , a granice minimalne / maksymalne mogą występować w dowolnej kolejności.

int myRand(int i_from, int i_to) {
  return (int)(Math.random() * (Math.abs(i_from - i_to) + 1)) + Math.min(i_from, i_to);
}

Ogólnie rzecz biorąc, znajduje bezwzględną odległość między granicami, pobiera odpowiednią wartość losową, a następnie przesuwa odpowiedź na podstawie dolnej granicy.

odporne na uszkodzenia
źródło