Generujesz losowe liczby całkowite w JavaScript w określonym zakresie?


1955

W jaki sposób można wygenerować losowe liczb całkowitych między dwoma określonymi zmiennych w JavaScript, np x = 4i y = 8będzie wyjście któregokolwiek 4, 5, 6, 7, 8?


1
oto przydatna treść: gist.github.com/kerimdzhanov/7529623
Dan KK

9
Na marginesie: dla tych, którzy używają npm i szukają szybkiego, niezawodnego i gotowego rozwiązania, istnieje lodash.losowy, który może być łatwo wymagany przy bardzo małym rozmiarze (zaimportuje tylko samą metodę, a nie całą lodash).
Nobita,

jeśli konieczne jest bezpieczne szyfrowanie developer.mozilla.org/en-US/docs/Web/API/RandomSource/…
szczęśliwy

Odpowiedzi:


3831

Istnieje kilka przykładów na stronie Mozilla Developer Network :

/**
 * 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;
}

Oto logika. To prosta zasada trzech:

Math.random()zwraca Numberod 0 (włącznie) do 1 (wyłącznie). Mamy więc taki interwał:

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

Chcielibyśmy teraz liczbę pomiędzy min(włącznie) a max(wyłącznie):

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

Możemy użyć, Math.randomaby uzyskać korespondenta w przedziale [min, maks.). Ale najpierw powinniśmy wziąć pod uwagę problem, odejmując minod drugiego przedziału:

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

To daje:

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

Możemy teraz złożyć wniosek, Math.randoma następnie obliczyć korespondenta. Wybierzmy liczbę losową:

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

Aby znaleźć x, zrobilibyśmy:

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

Nie zapomnij dodać z minpowrotem, aby uzyskać liczbę w przedziale [min, maks.):

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

To była pierwsza funkcja z MDN. Drugi zwraca liczbę całkowitą pomiędzy mini max, oba włącznie.

Teraz do uzyskania liczby całkowite, można użyć round, ceillub floor.

Możesz użyć Math.round(Math.random() * (max - min)) + min, ale daje to nierównomierną dystrybucję. Zarówno, mina maxtylko około połowę szansę na rolce:

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

Po maxwykluczeniu z przedziału ma jeszcze mniejszą szansę na wyrzucenie niż min.

Dzięki temu Math.floor(Math.random() * (max - min +1)) + minmasz idealnie równomierną dystrybucję.

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

Nie można używać ceil()i -1w tym równaniu, bo maxteraz miał nieco mniejsze szanse na rolki, ale można przechylać (niechciane) min-1skutkować zbyt.


10
Robi to tylko dlatego, że woła floor, co zaokrągla w dół.
Josh Stodola

4
@ thezachperson31 Możesz użyć round, ale oba mini maxtylko połowa szans na rzucenie , tak jak inne liczby. Możesz też odjąć jedną i wziąć ceil. To jednak pozostawia maxliczbę z minimalną mniejszą szansą na wyrzucenie ze względu na [0,1)Interwał.
Christoph

12
Utworzyłem JSFiddle, jeśli ktoś chce przetestować dystrybucję tej metody: jsfiddle.net/F9UTG/1
ahren

8
@JackFrost tak, zgadza się. Nie jesteś głupi, tylko się uczysz :)
Ionuț G. Stan

3
To pytanie jest stare, ale zrozumienie tej odpowiedzi zajęło mi zbyt wiele czasu Oo, myślę, że rozszerzenie matematyki.random w następnej wersji JavaScript byłoby trochę przydatne
Jonathan Ortega

527
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;

19
Wiem, że to BARDZO stara odpowiedź, ale korzystanie (Math.random() * (maximum - minimum + 1) ) << 0jest szybsze.
Ismael Miguel

11
@IsmaelMiguel Korzystanie z operatorów binarnych ( x << 0, x | 0, ~~x) zamiast Math.floor()nawróconych xw dwóch uzupełnienie ze znacznie mniejszym zakresie niż Number.MAX_SAFE_INTEGER(2³²⁻¹ vs. 2⁵³), więc trzeba go używać z rozwagą!
le_m

@ IsmaelMiguel Yo Właśnie próbowałem twojej metody w konsoli i losowo otrzymałem wartość ujemną! Math.randRange = (minimum, maksimum) => (Math.random () * (maksimum - minimum + 1)) << 0 Math.randRange (2,657348096152) -1407373159
bluejayke

@bluejayke Ponieważ 657348096152 (1001100100001100111111111111000010011000 w formacie binarnym) ma 40 bitów, a arytmetyka bitowa używa 32 bitów. Jeśli 657348096152|0otrzymasz 218099864 (1100111111111111000010011000 w formacie binarnym).
Ismael Miguel

1
To mądra odpowiedź. Wewnętrzne utworzenie zakresu [min, maks. + 1) faktycznie osiąga pożądany wynik, gdy [min, maks.] Jest jednocześnie włączone. Dziękuję Ci! :)
Mladen B.,

134

Math.random ()

Zwraca całkowitą liczbę losową między min (w zestawie ) i max (w zestawie ):

function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Lub dowolna liczba losowa od min (w zestawie ) do maks. ( Nie w zestawie ):

function randomNumber(min, max) {
  return Math.random() * (max - min) + min;
}

Przydatne przykłady (liczby całkowite):

// 0 -> 10
Math.floor(Math.random() * 11);

// 1 -> 10
Math.floor(Math.random() * 10) + 1;

// 5 -> 20
Math.floor(Math.random() * 16) + 5;

// -10 -> (-2)
Math.floor(Math.random() * 9) - 10;

** I zawsze miło przypomnieć (Mozilla):

Math.random () nie zapewnia kryptograficznie bezpiecznych liczb losowych. Nie używaj ich do niczego związanego z bezpieczeństwem. Zamiast tego użyj interfejsu API Web Crypto, a dokładniej metody window.crypto.getRandomValues ​​().


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

stosowanie:

var rollDie = getRandomizer( 1, 6 );

var results = ""
for ( var i = 0; i<1000; i++ ) {
    results += rollDie() + " ";    //make a string filled with 1000 random numbers in the range 1-6.
}

awaria:

Zwracamy funkcję (zapożyczanie z programowania funkcjonalnego), która po wywołaniu zwróci losową liczbę całkowitą między wartościami bottomi topwłącznie. Mówimy „włącznie”, ponieważ chcemy uwzględnić zarówno dolną, jak i górną część zakresu liczb, które można zwrócić. Tą drogą,getRandomizer( 1, 6 ) zwróci 1, 2, 3, 4, 5 lub 6.

(dół to niższa liczba, góra to większa liczba)

Math.random() * ( 1 + top - bottom )

Math.random()zwraca losowy podwójny od 0 do 1, a jeśli pomnożymy go przez jeden plus różnica między topi bottom, otrzymamy podwójną wartość pomiędzy 0a 1+b-a.

Math.floor( Math.random() * ( 1 + top - bottom ) )

Math.floorzaokrągla liczbę w dół do najbliższej liczby całkowitej. Mamy teraz wszystkie liczby całkowite między 0i top-bottom. 1 wygląda na mylące, ale musi tam być, ponieważ zawsze zaokrąglamy w dół, więc bez tego nigdy nie zostanie osiągnięta najwyższa liczba. Losowe dziesiętne generujemy musi mieścić się w przedziale 0do (1+top-bottom)tak możemy zaokrąglić w dół i uzyskać int w przedziale 0dotop-bottom

Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom

Kod w poprzednim przykładzie dał nam liczbę całkowitą w zakresie 0i top-bottomtak wszyscy musimy teraz zrobić, to dodać bottomdo tego wyniku, aby uzyskać całkowitą w zakresie bottomi topwłącznie. :RE


UWAGA: Jeśli wpiszesz najpierw wartość niecałkowitą lub większą liczbę, otrzymasz niepożądane zachowanie, ale chyba że ktoś o to poprosi, nie będę zagłębiał się w kod sprawdzania argumentów, ponieważ jest to raczej dalekie od intencji pierwotnego pytania .


1
Zdaję sobie sprawę, że jest to około 2,5 roku później, ale przy wejściach 1 i 6 twoja funkcja zwraca wartości 1, 2, 3, 4, 4 i 5, ale nigdy 6, tak jak by to było, gdyby było "włącznie".
jakieś

9
@some, Mogło być gorzej, mam 2½ roku + 1 dzień później ^^
ajax333221

+1, przetestowałem twój kod, wydaje się, że tworzy poprawną wartość. Kreatywna struktura do obsługi ustalonych scenariuszy, które mogą się często powtarzać w kodzie.
Chris

Dlaczego masz w tym celu funkcję?
Alph.Dev,

1
@ Alph.Dev Aby oddzielić logikę, która korzysta z generatora liczb losowych, od logiki, która decyduje dokładnie, jakiego rozkładu liczb losowych należy użyć. Gdy kod korzystający z generatora liczb losowych zaakceptuje go jako parametr (funkcja 0-argumentowa, która zawsze zwraca nową liczbę losową), może on działać z dowolnym generatorem liczb losowych.
Gordon Gustafson,

31
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

Alternatywnie, jeśli używasz Underscore.js , możesz użyć

_.random(min, max)

1
Podkreślenie zapewnia _.uniqueId()funkcję, którą można wywołać dla modeli po stronie klienta.
obfk

Korzystanie z operatorów binarnych ( x << 0, x | 0, ~~x) zamiast Math.floor()nawróconych xw dwóch uzupełnienie ze znacznie mniejszym zakresie niż Number.MAX_SAFE_INTEGER(2³²⁻¹ vs. 2⁵³), więc trzeba go używać z rozwagą!
le_m

30

Zwróć losową liczbę od 1 do 10:

Math.floor((Math.random()*10) + 1); 

Zwróć losową liczbę od 1 do 100:

Math.floor((Math.random()*100) + 1)

czy twoje „pomiędzy” obejmuje, czy wyklucza? tzn. czy to jest [1,10], [1,10), (1,10] lub (1,10)?
evandrix

1
Częściowo obejmuje: [1, *)
Ivan Z

jaka jest potrzeba +1 na końcu funkcji? Chyba działa idealnie.
Shachi

18

Jeśli potrzebujesz zmiennej między 0 a maksimum, możesz użyć:

Math.floor(Math.random() *  max);

Czy maks. Włącznik lub wyłączność>
Drzewo

2
@Tree przy użyciu Math.floor max jest wyłączny. Jeśli chcesz mieć maksimum, możesz użyć Math.round.
Łukasz

14

Pozostałe odpowiedzi nie uwzględniają idealnie rozsądnych parametrów 0i 1. Zamiast tego należy używać round zamiast z ceillub floor:

function randomNumber(minimum, maximum){
    return Math.round( Math.random() * (maximum - minimum) + minimum);
}

console.log(randomNumber(0,1));  # 0 1 1 0 1 0
console.log(randomNumber(5,6));  # 5 6 6 5 5 6
console.log(randomNumber(3,-1)); # 1 3 1 -1 -1 -1

1
Twoja odpowiedź jest prawdziwa, ale myślę, że twój przykład jest zły. console.log(randomNumber(5,6)); # 9 6 6 5 7 7Czy 9 i 7 występują między 5 a 6? ...... powinieneś to poprawić lub wyjaśnić ...
Sachin

12

Oto implementacja MS DotNet klasy Random w javascript-

var Random = (function () {
function Random(Seed) {
    if (!Seed) {
        Seed = this.milliseconds();
    }
    this.SeedArray = [];
    for (var i = 0; i < 56; i++)
        this.SeedArray.push(0);
    var num = (Seed == -2147483648) ? 2147483647 : Math.abs(Seed);
    var num2 = 161803398 - num;
    this.SeedArray[55] = num2;
    var num3 = 1;
    for (var i_1 = 1; i_1 < 55; i_1++) {
        var num4 = 21 * i_1 % 55;
        this.SeedArray[num4] = num3;
        num3 = num2 - num3;
        if (num3 < 0) {
            num3 += 2147483647;
        }
        num2 = this.SeedArray[num4];
    }
    for (var j = 1; j < 5; j++) {
        for (var k = 1; k < 56; k++) {
            this.SeedArray[k] -= this.SeedArray[1 + (k + 30) % 55];
            if (this.SeedArray[k] < 0) {
                this.SeedArray[k] += 2147483647;
            }
        }
    }
    this.inext = 0;
    this.inextp = 21;
    Seed = 1;
}
Random.prototype.milliseconds = function () {
    var str = new Date().valueOf().toString();
    return parseInt(str.substr(str.length - 6));
};
Random.prototype.InternalSample = function () {
    var num = this.inext;
    var num2 = this.inextp;
    if (++num >= 56) {
        num = 1;
    }
    if (++num2 >= 56) {
        num2 = 1;
    }
    var num3 = this.SeedArray[num] - this.SeedArray[num2];
    if (num3 == 2147483647) {
        num3--;
    }
    if (num3 < 0) {
        num3 += 2147483647;
    }
    this.SeedArray[num] = num3;
    this.inext = num;
    this.inextp = num2;
    return num3;
};
Random.prototype.Sample = function () {
    return this.InternalSample() * 4.6566128752457969E-10;
};
Random.prototype.GetSampleForLargeRange = function () {
    var num = this.InternalSample();
    var flag = this.InternalSample() % 2 == 0;
    if (flag) {
        num = -num;
    }
    var num2 = num;
    num2 += 2147483646.0;
    return num2 / 4294967293.0;
};
Random.prototype.Next = function (minValue, maxValue) {
    if (!minValue && !maxValue)
        return this.InternalSample();
    var num = maxValue - minValue;
    if (num <= 2147483647) {
        return parseInt((this.Sample() * num + minValue).toFixed(0));
    }
    return this.GetSampleForLargeRange() * num + minValue;
};
Random.prototype.NextDouble = function () {
    return this.Sample();
};
Random.prototype.NextBytes = function (buffer) {
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = this.InternalSample() % 256;
    }
};
return Random;
}());

Posługiwać się:

        var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal

Klasa MS DotNet Random objęta jest licencją Ms-RSL , co oznacza, że ​​jest chroniona prawem autorskim. Dlatego należy zachować ostrożność podczas korzystania z tego kodu pochodnego, ponieważ może on stanowić podstawę do spraw dotyczących naruszenia praw autorskich.
JohannesB

12

Użyj tej funkcji, aby uzyskać losowe liczby między podanym zakresem

function rnd(min,max){
    return Math.floor(Math.random()*(max-min+1)+min );
}

10

Po wygenerowaniu liczby losowej za pomocą programu komputerowego nadal jest uważana za liczbę losową, jeśli wybrana liczba jest częścią lub pełną liczbą początkową. Ale jeśli to się zmieniło, wówczas matematycy nie przyjmą go jako liczby losowej i mogą nazwać to liczbą stronniczą. Ale jeśli opracowujesz program do prostego zadania, nie będzie to do rozważenia. Ale jeśli opracowujesz program do generowania losowej liczby dla wartościowych rzeczy, takich jak program loteryjny lub gra hazardowa, wówczas Twój program zostanie odrzucony przez kierownictwo, jeśli nie będziesz rozważał powyższego przypadku.

Oto propozycja dla tych ludzi:

Wygeneruj liczbę losową za pomocą Math.random(). (Powiedz to n)

Now for [0,10) ==>  n*10 (i.e. one digit) and for[10,100) ==> n*100 (i.e. two digits) and so on. Here squire bracket indicates that boundary is inclusive and round bracket indicates boundary is exclusive.
Then remove the rest after the decimal point. (i.e. get floor) - using Math.floor(), this can be done.

Jeśli wiesz, jak odczytać tabelę liczb losowych, aby wybrać liczbę losową, wiesz, że powyższy proces (pomnożenie przez 1, 10, 100 itd.) Nie narusza tego, o którym mówiłem na początku (ponieważ zmienia tylko miejsce przecinka dziesiętnego).

Przestudiuj poniższy przykład i opracuj go według własnych potrzeb.

Jeśli potrzebujesz próbki [0,9], to odpowiedź n * 10 jest odpowiedzią, a jeśli potrzebujesz [0,99], to odpowiedź n * 100 jest odpowiedzią i tak dalej.

Teraz wejdź w swoją rolę:

Poprosiłeś liczby z określonego zakresu. (W tym przypadku jesteś stronniczy w tym zakresie. - Biorąc liczbę z [1,6] rzucając kością, to jesteś stronniczy w [1,6], ale nadal jest losowy, jeśli i tylko jeśli kość jest bezstronna .)

Rozważ więc swój zakres ==> [78, 247] liczba elementów zakresu = 247 - 78 + 1 = 170; (ponieważ obie granice są włącznie.

/*Mthod 1:*/
    var i = 78, j = 247, k = 170, a = [], b = [], c, d, e, f, l = 0;
    for(; i <= j; i++){ a.push(i); }
    while(l < 170){
        c = Math.random()*100; c = Math.floor(c);
        d = Math.random()*100; d = Math.floor(d);
        b.push(a[c]); e = c + d;
        if((b.length != k) && (e < k)){  b.push(a[e]); }
        l = b.length;
    }
    console.log('Method 1:');
    console.log(b);
/*Method 2:*/

    var a, b, c, d = [], l = 0;
    while(l < 170){
        a = Math.random()*100; a = Math.floor(a);
        b = Math.random()*100; b = Math.floor(b);
        c = a + b;
        if(c <= 247 || c >= 78){ d.push(c); }else{ d.push(a); }
        l = d.length;
    }
    console.log('Method 2:');
    console.log(d);

Uwaga: W metodzie pierwszej najpierw stworzyłem tablicę zawierającą potrzebne liczby, a następnie losowo umieściłem je w innej tablicy. W metodzie drugiej generuj liczby losowo i sprawdź, czy mieszczą się w wymaganym zakresie. Następnie umieść go w tablicy. Tutaj wygenerowałem dwie liczby losowe i wykorzystałem je wszystkie, aby zmaksymalizować szybkość programu poprzez zminimalizowanie wskaźnika awaryjności w celu uzyskania użytecznej liczby. Jednak dodanie wygenerowanych liczb da również trochę stronniczości. Poleciłbym więc moją pierwszą metodę generowania liczb losowych w określonym zakresie.

W obu metodach konsola wyświetli wynik (naciśnij klawisz F12 w Chrome, aby otworzyć konsolę)


3
„losowy” niekoniecznie oznacza „równomiernie rozmieszczony”. „stronniczy” nie oznacza „nieprzypadkowy”. losowe oznacza pochodzące z rozkładu prawdopodobieństwa.
syzygy

6
Ledwo potrafię powiedzieć, co próbuje odpowiedzieć ta odpowiedź. Jeśli jednak potrzebujesz losowych liczb do celów takich jak numery loterii i hazard. Po pierwsze, prawdopodobnie nie powinieneś generować ich na kliencie. Po drugie, potrzebujesz kryptograficznie bezpiecznego generatora liczb losowych, a dostarczone algo nie jest wystarczające. Wielokrotne wywoływanie losowe nie powoduje, że wynik jest „losowy”. Autor wydaje się być zaniepokojony uprzedzeniami, ale nie zapewnia dobrego algo, aby temu zapobiec. W rzeczywistości inne dostarczone krótkie odpowiedzi dają bezstronne losowe liczby (zakładając, że leżący u ich podstaw generator losowy jest bezstronny).
Jeff Walker Code Ranger

@JeffWalkerCodeRanger Myślę, że miał na myśli to, że z „normalnym” algorytmem [tj. Math.floor(Math.random() * (6 - 1 + 1) + 1)] Liczby 1 i 6 z konieczności będą walcowane mniej niż 2, 3, 4 i 5. Różnica jest jednak w zasadzie nieistotna.
oldboy

10

Aby uzyskać losową liczbę całkowitą z zakresem, spróbuj:

function random(minimum, maximum) {
  var bool = true;

  while (bool) {
    var number = (Math.floor(Math.random() * maximum + 1) + minimum);
    if (number > 20) {
      bool = true;
    } else {
      bool = false;
    }
  }

  return number;
}

8
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)));
}

Aby przetestować tę funkcję i jej odmiany, zapisz poniższy kod HTML / JavaScript w pliku i otwórz w przeglądarce. Kod wygeneruje wykres pokazujący rozkład miliona wywołań funkcji. Kod zapisuje również przypadki na krawędziach, więc jeśli funkcja wygeneruje wartość większą niż maksimum lub mniejszą niż min, będziesz wiedział.

<html>
    <head>
        <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 <= (max - min) + 2; i++) {
          array.push(0);
        }

        for(var i = 0; i < 1000000; i++) {
            var random = getRandomInt(min, max);
            array[random - min + 1]++;
        }

        var maxSample = 0;
        for(var i = 0; i < max - min; i++) {
            maxSample = Math.max(maxSample, array[i]);
        }

        //create a bar graph to show the sample distribution
        var maxHeight = 500;
        for(var i = 0; i <= (max - min) + 2; i++) {
            var sampleHeight = (array[i]/maxSample) * maxHeight;

            document.write('<span style="display:inline-block;color:'+(sampleHeight == 0 ? 'black' : 'white')+';background-color:black;height:'+sampleHeight+'px">&nbsp;[' + (i + min - 1) + ']:&nbsp;'+array[i]+'</span>&nbsp;&nbsp;');
        }
        document.write('<hr/>');
        </script>
    </head>
    <body>

    </body>
</html>

7

Aby uzyskać liczbę losową, powiedzmy między 1 a 6, najpierw:

    0.5 + (Math.random() * ((6 - 1) + 1))

To mnoży liczbę losową przez 6, a następnie dodaje do niej 0,5. Następnie zaokrąglij liczbę do dodatniej liczby całkowitej, wykonując:

    Math.round(0.5 + (Math.random() * ((6 - 1) + 1))

Zaokrągla liczbę do najbliższej liczby całkowitej.

Aby uczynić to bardziej zrozumiałym, wykonaj następujące czynności:

    var value = 0.5 + (Math.random() * ((6 - 1) + 1))
    var roll = Math.round(value);
    return roll;

Zasadniczo kod do wykonania tego przy użyciu zmiennych to:

    var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
    var roll = Math.round(value);
    return roll;

Powodem odebrania 0,5 wartości minimalnej jest to, że samo użycie wartości minimalnej pozwoliłoby uzyskać liczbę całkowitą, która była o jeden większa od wartości maksymalnej. Odejmując 0,5 od wartości minimalnej, zasadniczo zapobiegasz zaokrąglaniu wartości maksymalnej.

Mam nadzieję, że to pomaga.


Jeśli wykluczasz 0 , nie ma sensu „zaokrąglać” zakresu od 0 do 0,5.
ILMostro_7

7

Za pomocą następującego kodu możesz wygenerować tablicę liczb losowych, bez powtarzania, w danym zakresie.

function genRandomNumber(how_many_number,min,max) {

            // parameters
            // how_many_number : how many numbers you want to generate. For example it is 5.
            // min(inclusive) : minimum/low value of a range. it must be any positive integer but less than max. i.e 4
            // max(inclusive) : maximun value of a range. it must be any positive integer. i.e 50
            // return type: array

            var random_number = [];
            for (var i = 0; i < how_many_number; i++) {
                var gen_num = parseInt((Math.random() * (max-min+1)) + min);
                do {
                    var is_exist = random_number.indexOf(gen_num);
                    if (is_exist >= 0) {
                        gen_num = parseInt((Math.random() * (max-min+1)) + min);
                    }
                    else {
                        random_number.push(gen_num);
                        is_exist = -2;
                    }
                }
                while (is_exist > -1);
            }
            document.getElementById('box').innerHTML = random_number;
        }

7

Wiem, że na to pytanie już udzielono odpowiedzi, ale moja odpowiedź może komuś pomóc.

Znalazłem tę prostą metodę na W3Schools:

Math.floor((Math.random() * max) + min);

Mam nadzieję, że to komuś pomoże.


1
Math.floor ((Math.random () * 1) + 0); zawsze daje 0
madprops

1
@madprops Ponieważ maksymalna liczba jest wyłączna. Aby uzyskać 0 lub 1, należy ustawić 2 jako liczbę maksymalną.
NutCracker

1
lub dodajesz + 1 w funkcji wywołującej tę metodę
Pietro Coelho,

6

Losowa liczba całkowita od najniższej do najwyższej:

function randomRange(l,h){
  var range = (h-l);
  var random = Math.floor(Math.random()*range);
  if (random === 0){random+=1;}
  return l+random;
}

Nie jest to najbardziej eleganckie rozwiązanie ... ale coś szybkiego.


5

Oto, czego używam do generowania liczb losowych.

function random(high,low) {
    high++;
    return Math.floor((Math.random())*(high-low))+low;
}

Wykonujemy, high++ponieważ Math.random()generuje losową liczbę od 0 (włącznie) i 1 (wyłącznie) Ta wykluczona oznacza, że ​​musimy zwiększyć najwyższą wartość o jeden przed wykonaniem jakiejkolwiek matematyki. Następnie odejmujemy niski od wysokiego, dając nam najwyższą liczbę do wygenerowania - niską, a następnie + niską, przywracając wysoką wartość z powrotem do normalnej, a najniższą liczbę co najmniej najniższą. następnie zwracamy wynikową liczbę

random(7,3) może wrócić 3,4,5,6, or 7


2
Ponieważ highjest używany tylko raz, równie dobrze możesz użyć high-low+1zamiast osobnej instrukcji przyrostu. Ponadto większość użytkowników spodziewałaby się, że lowparametr będzie na pierwszym miejscu.
Chris Walsh

4
    <!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8" />
    </head>
    <body>
        <script>
            /*

                assuming that window.crypto.getRandomValues is available
                the real range would be fron 0 to 1,998 instead of 0 to 2,000
                See javascript documentation for explanation
                https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues
            */
            var array = new Uint8Array(2);
            window.crypto.getRandomValues(array);
            console.log(array[0] + array[1]);

        </script>
    </body>
</html>

Uint8Array tworzy tablicę wypełnioną liczbą do 3 cyfr, która może wynosić maksymalnie 999. Ten kod jest bardzo krótki.


4

Oto przykład funkcji javascript, która może generować losową liczbę o dowolnej określonej długości bez użycia Math.random ():

    function genRandom(length)
    {
     const t1 = new Date().getMilliseconds();
     var min = "1",max = "9";
     var result;
     var numLength = length;
     if (numLength != 0)
     {
        for (var i = 1; i < numLength; i++)
        {
           min = min.toString() + "0";
           max = max.toString() + "9";
        }
     } 
     else
     {
        min = 0;
        max = 0;
        return; 
     }

      for (var i = min; i <= max; i++)
      {
           //Empty Loop
      }

      const t2 = new Date().getMilliseconds();
      console.log(t2);
      result = ((max - min)*t1)/t2;
      console.log(result);
      return result;
    }

t1 / t2 zawsze bardzo bliżej 1. i dlatego twoja funkcja zwraca ten sam numer, gdy funkcja jest wywoływana powtarzalnie .. jsbin.com/xogufacera/edit?js,console
Sunil BN

sprawdź adres jsbin .. sam zobaczysz wynik
Sunil BN

Działa świetnie, gdy długość wynosi między 4-10 (jak testowałem na mojej maszynie), ponieważ wartości stałych T1 i T2 powinny mieć odpowiednią odległość.
Nilesh Pawar

3

to jest moje zdanie na temat liczby losowej w zakresie, ponieważ chciałem uzyskać liczbę losową w zakresie od podstawy do wykładnika. np. podstawa = 10, wykładnik = 2, daje liczbę losową od 0 do 100, idealnie itd.

jeśli to pomaga w użyciu, oto:

// get random number within provided base + exponent
// by Goran Biljetina --> 2012

function isEmpty(value){
    return (typeof value === "undefined" || value === null);
}
var numSeq = new Array();
function add(num,seq){
    var toAdd = new Object();
     toAdd.num = num;
     toAdd.seq = seq;
     numSeq[numSeq.length] = toAdd;
}
function fillNumSeq (num,seq){
    var n;
    for(i=0;i<=seq;i++){
        n = Math.pow(num,i);
        add(n,i);
    }
}
function getRandNum(base,exp){
    if (isEmpty(base)){
        console.log("Specify value for base parameter");
    }
    if (isEmpty(exp)){
        console.log("Specify value for exponent parameter");
    }
    fillNumSeq(base,exp);
    var emax;
    var eseq;
    var nseed;
    var nspan;
    emax = (numSeq.length);
    eseq = Math.floor(Math.random()*emax)+1;
    nseed = numSeq[eseq].num;
    nspan = Math.floor((Math.random())*(Math.random()*nseed))+1;
    return Math.floor(Math.random()*nspan)+1;
}

console.log(getRandNum(10,20),numSeq);
//testing:
//getRandNum(-10,20);
//console.log(getRandNum(-10,20),numSeq);
//console.log(numSeq);

3

Math.random() jest szybki i odpowiedni do wielu celów, ale nie jest odpowiedni, jeśli potrzebujesz bezpiecznych kryptograficznie wartości (nie jest bezpieczny) lub jeśli potrzebujesz liczb całkowitych z całkowicie jednorodnego rozkładu bezstronnego (metoda mnożenia stosowana w innych odpowiedziach nieco częściej wytwarza określone wartości niż inni).

W takich przypadkach możemy użyć crypto.getRandomValues() do wygenerowania bezpiecznych liczb całkowitych i odrzucić wszelkie wygenerowane wartości, których nie możemy jednolicie odwzorować w zakresie docelowym. Będzie to wolniejsze, ale nie powinno być znaczące, chyba że generujesz wyjątkowo dużą liczbę wartości.

Aby wyjaśnić problem z tendencyjnym rozkładem, rozważ przypadek, w którym chcemy wygenerować wartość między 1 a 5, ale mamy generator liczb losowych, który wytwarza wartości między 1 a 16 (wartość 4-bitowa). Chcemy, aby ta sama liczba wygenerowanych wartości została odwzorowana na każdą wartość wyjściową, ale 16 nie dzieli się równomiernie przez 5: pozostawia pozostałą część 1. Musimy więc odrzucić 1 z możliwych wygenerowanych wartości i kontynuować tylko, gdy otrzymamy jedna z 15 mniejszych wartości, które mogą być jednolicie odwzorowane w naszym zakresie docelowym. Nasze zachowanie może wyglądać następująco:

Generate a 4-bit integer in the range 1-16.
If we generated  1,  6, or 11 then output 1.
If we generated  2,  7, or 12 then output 2.
If we generated  3,  8, or 13 then output 3.
If we generated  4,  9, or 14 then output 4.
If we generated  5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.

Poniższy kod wykorzystuje podobną logikę, ale generuje 32-bitową liczbę całkowitą, ponieważ jest to największy wspólny rozmiar liczby całkowitej, który może być reprezentowany przez standardowy numbertyp JavaScript . (Można to zmienić, aby użyć BigInts, jeśli potrzebujesz większego zakresu.) Niezależnie od wybranego zakresu, część wygenerowanych wartości, które są odrzucane, zawsze będzie mniejsza niż 0,5, więc oczekiwana liczba odrzuceń będzie zawsze mniejsza niż 1,0 i zwykle blisko 0,0; nie musisz się martwić, że zapętli się na zawsze.

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]



1

Możesz zrobić ten fragment kodu,

let randomNumber = function(first,second){
let number = Math.floor(Math.random()*Math.floor(second));
while(number<first){

    number = Math.floor(Math.random()*Math.floor(second));
}
return number;
}

1
Jest tutaj niepotrzebna zduplikowana linia. Po prostu użyj do - whilezamiastwhile
Javi Marzán

1

Ionuț G. Stan napisał świetną odpowiedź, ale było to dla mnie zbyt skomplikowane. Znalazłem więc jeszcze prostsze wyjaśnienie tych samych pojęć na https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1-min-explanation przez Jasona Anello.

UWAGA: Jedyną ważną rzeczą, którą powinieneś wiedzieć przed przeczytaniem wyjaśnień Jasona, jest definicja „obcięcia”. Używa tego terminu przy opisywaniu Math.floor(). Słownik Oxford definiuje „obcinać” jako:

Skróć (coś), odcinając górę lub koniec.


0

Może to obsłużyć generowanie do 20 cyfr niepowtarzalnej liczby losowej

JS

var generatedNumbers = [];

function generateRandomNumber(precision) { // precision --> number precision in integer 
    if (precision <= 20) {
        var randomNum = Math.round(Math.random().toFixed(precision) * Math.pow(10, precision));
        if (generatedNumbers.indexOf(randomNum) > -1) {
            if (generatedNumbers.length == Math.pow(10, precision))
                return "Generated all values with this precision";
                return generateRandomNumber(precision);
        } else {
            generatedNumbers.push(randomNum);
            return randomNum;
        }
    } else
       return "Number Precision shoould not exceed 20";
}
generateRandomNumber(1);

wprowadź opis zdjęcia tutaj

JsFiddle


Głosuję za tym tylko dlatego.
Taylor Ackley

1
@TaylorAckley Ta odpowiedź nie dotyczy pytania.
RomainValeri

0

/ * Napisz wywoływaną funkcję, randUpToktóra akceptuje liczbę i zwraca losową liczbę całkowitą od 0 do tej liczby? * /

var randUpTo = function(num) {
    return Math.floor(Math.random() * (num - 1) + 0);
};

/ * Napisz nazwaną funkcję, randBetweenktóra akceptuje dwie liczby reprezentujące zakres i zwraca losową liczbę całkowitą między tymi dwiema liczbami. * /

var randBetween = function (min, max) {
    return Math.floor(Math.random() * (max - min - 1)) + min;
};

/ * Napisz wywoływaną funkcję, randFromTillktóra akceptuje dwie liczby reprezentujące zakres i zwraca liczbę losową między min (włącznie) i max (wyłącznie). * /

var randFromTill = function (min, max) {
    return Math.random() * (max - min) + min;
};

/ * Napisz wywoływaną funkcję, randFromToktóra akceptuje dwie liczby reprezentujące zakres i zwraca losową liczbę całkowitą między min (włącznie) i max (włącznie) * /

var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};

1
Piękna, czy możesz również zauważyć, że randBetween jest (wyłączny) (wyłączny)?
pfdint

0

Zrobiłem tę funkcję, która bierze pod uwagę opcje takie jak min, max, exclude (lista ints do wykluczenia) i seed (na wypadek, gdybyś chciał rozstawionego generatora losowego).

get_random_int = function(args={})
{
    let def_args =
    {
        min: 0,
        max: 1,
        exclude: false,
        seed: Math.random
    }

    args = Object.assign(def_args, args)

    let num = Math.floor(args.seed() * (args.max - args.min + 1) + args.min)

    if(args.exclude)
    {
        let diff = args.max - args.min
        let n = num

        for(let i=0; i<diff*2; i++)
        {
            if(args.exclude.includes(n))
            {
                if(n + 1 <= args.max)
                {
                    n += 1
                }

                else
                {
                    n = args.min
                }
            }

            else
            {
                num = n
                break
            }
        }
    }

    return num
}

Może być używany jak:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1,
        exclude: [3, 6, 5],
        seed: my_seed_function
    }
)

Lub prościej:

let n = get_random_int
(
    {
        min: 0,
        max: some_list.length - 1
    }
)

Następnie możesz zrobić:

let item = some_list[n]

Gist: https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e


0
  • random (min, max) generuje losową liczbę między min (włącznie) i max (wyłącznie)
  • Math.floor zaokrągla liczbę w dół do najbliższej liczby całkowitej

    function generateRandomInteger (min, max) { 
        return Math.floor(random(min,max)) 
    }`

Aby więc wygenerować losową liczbę całkowitą od 4 do 8 włącznie, wywołaj powyższą funkcję z następującymi argumentami:

generateRandomInteger (4,9)

0

Moja metoda generowania liczb losowych od 0 do n, gdzie n <= 10 (n wykluczone):

Math.floor((Math.random() * 10) % n)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.