2009-11-10 9 views
31

Je sais que je peux générer des flottants aléatoires avec rand (max). J'ai essayé de générer un flottant dans une gamme, cela ne devrait pas être difficile. Mais par exemple rand (1.4512) renvoie 0, donc rand ne calcule pas avec des flottants. Maintenant, j'ai essayé une petite astuce, en convertissant la chose en nombre entier et après avoir randomisé un nombre approprié dans ma gamme désirée, en le calculant de nouveau à un flotteur .. qui ne fonctionne pas.Comment créer au mieux un flottant aléatoire dans une plage entre deux flotteurs

Ma question est comment faire cela d'une meilleure façon. S'il n'y a pas de meilleur moyen, pourquoi celui-ci ne fonctionne-t-il pas? (Peut-être qu'il est trop tard pour moi, j'aurais dû commencer à dormir il y a 2 heures ..). Le tout vise à être une méthode de calcul d'un champ "position" pour les enregistrements de base de données afin que les utilisateurs puissent les commander manuellement. Je n'ai jamais fait quelque chose comme ça avant, peut-être que quelqu'un peut me suggérer une meilleure solution.

Voici le code à ce jour:

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 

Merci!

+0

Si les réponses ci-dessous sont inacceptables, pourriez-vous s'il vous plaît préciser le problème? – Josh

+0

Merci à tous pour vos réponses, propre et bien expliqué – pduersteler

+0

La réponse de @ sandor_bedo est probablement la meilleure ici: 'rand (-34.0..53.8) ' – Automatico

Répondre

38

Récapitulons:

rand() va générer un (psuedo-) flottant aléatoire entre 0 et 1.

rand (int) va générer un nombre aléatoire (de psuedo-) entre 0 et int.

donc quelque chose comme:

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

devrait faire bien.

Mise à jour:

testé avec un juste petit test unitaire:

def testRange 
    min = 1 
    max = 100 

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

a l'air bien.

+0

cherchait un moyen d'implémenter les plages aléatoires de Ruby 1.9.3 dans JRuby. Cela fonctionne très bien! – KChaloux

3

Je pense que le mieux est d'utiliser rand() pour générer un flotteur aléatoire entre 0 et 1, puis multiplier pour définir la plage et ajouter à définir le décalage:

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

Note: depuis la l'ordre des termes n'a pas d'importance, faire end_num par défaut à 0 vous permet d'obtenir un flottement aléatoire entre 0 et x avec float_rand (x).

10

1.9 et 2.0, vous pouvez donner un argument de plage 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

C'est la meilleure réponse. – Automatico

61

Passez un entier gamme de flotteurs rand

Si vous voulez « créer un flotteur aléatoire dans un intervalle compris entre deux flotteurs ", il suffit de passer une gamme de flotteurs à rand.

rand(11.2...76.9) 

(Testé avec Ruby 2.1)

+0

Ceci est la bonne réponse. Plus précisément, à partir des docs ruby: "Quand [donné] un' Range', 'rand' renvoie un nombre aléatoire où' range.member? (Number) == true' ". – omnikron

+0

Cela devrait être la réponse acceptée! – gregblass

Questions connexes