Willekeurige gehele getallen genereren in JavaScript in een specifiek bereik?

Hoe kan ik willekeurige gehele getallen genereren tussen twee gespecificeerde variabelen in JavaScript, bijv. x = 4 en y = 8 zou een willekeurig van 4, 5, 6, 7, 8 opleveren?

Oplossing

Er staan enkele voorbeelden op de Mozilla Developer Network pagina:

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Hier is de logica erachter. Het is een simpele regel van drie:

Math.random() geeft een getal tussen 0 (inclusief) en 1 (exclusief). Dus we hebben een interval als dit:

[0 .................................... 1)

Nu, we willen een getal tussen min (inclusief) en max (exclusief):

[0 .................................... 1)
[min .................................. max)

We kunnen Math.random gebruiken om de overeenkomstige waarde in het [min, max] interval te krijgen. Maar, eerst moeten we het probleem een beetje ontbinden door min van het tweede interval af te trekken:

[0 .................................... 1)
[min - min ............................ max - min)

Dit geeft:

[0 .................................... 1)
[0 .................................... max - min)

We kunnen nu Math.random toepassen en dan het overeenkomstige uitrekenen. Laten we een willekeurig getal kiezen:

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (what we need)

Dus, om x te vinden, zouden we doen:

x = Math.random() * (max - min);

Vergeet niet min weer toe te voegen, zodat we een getal in het [min, max] interval krijgen:

x = Math.random() * (max - min) + min;

Dat was de eerste functie van MDN. De tweede, geeft een geheel getal tussen min en max, beide inclusief.

Om gehele getallen te krijgen, kun je round, ceil of floor gebruiken.

Je zou Math.round(Math.random() * (max - min)) + min, dit geeft echter een ongelijke verdeling. Zowel min als max hebben maar ongeveer de helft van de kans om te rollen:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘   ← Math.round()
   min          min+1                          max

Als max van het interval wordt uitgesloten, heeft deze nog minder kans om te rollen dan min.

Met Math.floor(Math.random() * (max - min +1)) + min heb je een perfect gelijke verdeling.

min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
|        |        |         |        |        |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘   ← Math.floor()
   min     min+1               max-1    max

Je kunt ceil() en -1 niet gebruiken in die vergelijking omdat max nu iets minder kans had om te rollen, maar je kunt het (ongewenste) min-1 resultaat ook rollen.

Commentaren (29)
function getRandomizer(bottom, top) {
    return function() {
        return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
    }
}

gebruik:


var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i
Commentaren (7)
function getRandomInt(lower, upper)
{
    //to create an even sample distribution
    return Math.floor(lower + (Math.random() * (upper - lower + 1)));

    //to produce an uneven sample distribution
    //return Math.round(lower + (Math.random() * (upper - lower)));

    //to exclude the max value from the possible values
    //return Math.floor(lower + (Math.random() * (upper - lower)));
}

Om deze functie, en variaties op deze functie, te testen, sla de onderstaande HTML/JavaScript op in een bestand en open het met een browser. De code zal een grafiek maken met de verdeling van een miljoen functie-aanroepen. De code zal ook de randgevallen registreren, dus als de functie een waarde produceert die groter is dan de max, of kleiner dan de min, dan.zul.je.dat.weten.




        <script type="text/javascript">
        function getRandomInt(lower, upper)
        {
            //to create an even sample distribution
            return Math.floor(lower + (Math.random() * (upper - lower + 1)));

            //to produce an uneven sample distribution
            //return Math.round(lower + (Math.random() * (upper - lower)));

            //to exclude the max value from the possible values
            //return Math.floor(lower + (Math.random() * (upper - lower)));
        }

        var min = -5;
        var max = 5;

        var array = new Array();

        for(var i = 0; i 
Commentaren (0)