2009-11-10 16 views
31

Wiem, że mogę generować losowe pływaki z randem (max). Próbowałem generować zmienną w zakresie, nie powinno to być trudne. Ale np. Rand (1.4512) zwraca 0, więc rand nie oblicza za pomocą spławików. Teraz wypróbowałem małą sztuczkę, przekształcając rzecz w liczbę całkowitą i po losowaniu numeru dopasowania w moim pożądanym zakresie, obliczając go z powrotem na pływak ... który nie działa.Jak najlepiej utworzyć losowy float w zakresie między dwoma pływakami

Moje pytanie brzmi: jak to zrobić w lepszy sposób. Jeśli nie ma lepszego sposobu, dlaczego ten nie działa? (Może dla mnie już za późno, powinienem był spać 2 godziny temu ...). Całość ma być metodą obliczania pola "pozycji" dla rekordów bazy danych, aby użytkownicy mogli zamawiać je ręcznie. Nigdy wcześniej czegoś takiego nie robiłem, może ktoś może mi wskazać lepsze rozwiązanie.

Oto kod do tej pory:

def calculate_position(@elements, index) 
    min = @elements[index].position 

    if @elements[index + 1].nil? 
     pos = min + 1 
    else 
     pos = min + (rand(@elements[index + 1].position * 10000000000)/10000000000) 
    end 

    return pos 
end 

Dzięki!

+0

Jeśli odpowiedzi poniżej są nie do przyjęcia, czy mógłbyś wyjaśnić ten problem? – Josh

+0

Dziękuję wszystkim za odpowiedzi, czyste i dobrze wyjaśnione – pduersteler

+0

@ Odpowiedź sandor_bedo jest prawdopodobnie najlepsza tutaj: 'rand (-34.0..53.8) ' – Automatico

Odpowiedz

38

Zreasumujmy:

LOS() generuje (psuedo-) losowo pływający pomiędzy 0 i 1.

LOS (int) generuje (psuedo-) losową liczbę całkowitą pomiędzy 0 i int.

Więc coś takiego:

def range (min, max) 
    rand * (max-min) + min 
end 

powinien zrobić ładnie.

Aktualizacja:

tylko przetestowane z trochę testów jednostkowych:

def testRange 
    min = 1 
    max = 100 

    1_000_000.times { 
     result = range min, max 
     print "ERROR" if result < min || result > max 
    } 
end 

wygląda dobrze.

+0

Szukał sposobu na wdrożenie losowych zakresów Ruby 1.9.3 w JRuby. Działa to świetnie! – KChaloux

3

Myślę, że najlepiej jest użyć rand(), aby wygenerować losowy pływaka między 0 a 1, a następnie pomnożyć ustawić zakres i dodać, aby ustawić offset:

def float_rand(start_num, end_num=0) 
    width = end_num-start_num 
    return (rand*width)+start_num 
end 

Uwaga: Ponieważ kolejność terminów nie ma znaczenia, dzięki czemu end_num default na 0 pozwala uzyskać losowy float między 0 a x z float_rand (x).

10

W 1.9 i 2.0 można podać zakres argumentu rand:

irb(main):001:0> 10.times { puts rand Math::E..Math::PI } 
3.0656267148715446 
2.7813979580609587 
2.7661725184200563 
2.9745784681934655 
2.852157154320737 
2.741063222095785 
2.992638029938756 
3.0713152547478866 
2.879739743508003 
2.7836491029737407 
=> 10 
+0

To jest lepsza odpowiedź. – Automatico

61

zdać szereg pływaki do rand

Jeśli chce „stworzyć losową pływaka w przedziale pomiędzy dwoma pływakami ", po prostu przekazuj zakres płynów do rand.

rand(11.2...76.9) 

(Testowane z Ruby 2.1)

+0

To jest poprawna odpowiedź. Konkretnie, z ruby ​​docs: "Kiedy [dany]" Range ",' rand' zwraca losową liczbę gdzie 'range.member? (Number) == true'". – omnikron

+0

To powinna być zaakceptowana odpowiedź! – gregblass

Powiązane problemy