Menghasilkan bilangan bulat acak dalam JavaScript dalam rentang tertentu?

1955

Bagaimana saya bisa menghasilkan bilangan bulat acak antara dua variabel yang ditentukan dalam JavaScript, mis x = 4dan y = 8akan menghasilkan salah satu 4, 5, 6, 7, 8?

zacharyliu
sumber
1
di sini adalah intisari yang berguna: gist.github.com/kerimdzhanov/7529623
Dan KK
9
Sebagai catatan: bagi mereka yang menggunakan npm dan mencari solusi yang cepat, andal, dan siap pakai ada lodash.random yang dapat dengan mudah diperlukan dengan tapak yang sangat kecil (itu akan mengimpor hanya metode itu sendiri dan bukan seluruh Lodash).
Nobita

Jawaban:

3834

Ada beberapa contoh di halaman Jaringan Pengembang Mozilla :

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

Inilah logika di baliknya. Ini aturan sederhana tiga:

Math.random()mengembalikan a Numberantara 0 (inklusif) dan 1 (eksklusif). Jadi kita memiliki interval seperti ini:

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

Sekarang, kami ingin nomor antara min(inklusif) dan max(eksklusif):

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

Kita dapat menggunakan Math.randomuntuk mendapatkan koresponden dalam interval [min, maks). Tetapi, pertama-tama kita harus memfaktorkan sedikit masalah dengan mengurangi mindari interval kedua:

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

Ini memberi:

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

Kami sekarang dapat menerapkan Math.randomdan kemudian menghitung koresponden. Mari kita pilih nomor acak:

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

Jadi, untuk menemukan x, kami akan melakukan:

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

Jangan lupa untuk menambahkan minkembali, sehingga kami mendapatkan nomor dalam interval [min, maks):

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

Itu adalah fungsi pertama dari MDN. Yang kedua, mengembalikan bilangan bulat antara mindanmax , keduanya inklusif.

Sekarang untuk mendapatkan bilangan bulat, Anda bisa menggunakan round, ceilatau floor.

Anda dapat menggunakan Math.round(Math.random() * (max - min)) + min, namun ini memberikan distribusi yang tidak rata. Keduanya, mindan maxhanya memiliki sekitar setengah peluang untuk bergulir:

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

Dengan maxdikecualikan dari interval, itu memiliki peluang lebih kecil untuk bergulir daripada min.

Dengan Math.floor(Math.random() * (max - min +1)) + minAnda memiliki distribusi yang merata.

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

Anda tidak dapat menggunakan ceil()dan -1dalam persamaan itu karena maxsekarang memiliki sedikit peluang untuk menggulung, tetapi Anda juga dapat menggulung hasil (yang tidak diinginkan) min-1.

Ionuț G. Stan
sumber
10
Itu hanya melakukan itu karena itu panggilan floor, yang membulatkan ke bawah.
Josh Stodola
4
@ thezachperson31 Anda dapat menggunakan round, tetapi kemudian keduanya, mindan maxhanya memiliki setengah kesempatan untuk memutar seperti yang dilakukan nomor-nomor lainnya. Anda juga bisa mengurangi satu dan mengambil ceil. Namun hal ini meninggalkan maxangka dengan kesempatan lebih sedikit untuk menggulung karena [0,1)Interval.
Christoph
12
Saya telah membuat JSFiddle jika ada yang ingin menguji distribusi metode ini: jsfiddle.net/F9UTG/1
ahren
8
@ JackFrost ya, itu benar. Anda tidak bodoh, Anda hanya belajar :)
Ionuț G. Stan
3
Pertanyaan ini sudah lama, tetapi memahami jawaban ini membuat saya terlalu banyak waktu Oo, saya pikir memperluas math.random pada versi JavaScript berikutnya akan menjadi semacam berguna
Jonathan Ortega
527
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
Darin Dimitrov
sumber
19
Saya tahu ini adalah jawaban yang SANGAT lama, tetapi menggunakan (Math.random() * (maximum - minimum + 1) ) << 0lebih cepat.
Ismael Miguel
11
@IsmaelMiguel Menggunakan operator biner ( x << 0, x | 0, ~~x) bukannya Math.floor()bertobat xmenjadi dua pelengkap dengan berbagai jauh lebih kecil dari Number.MAX_SAFE_INTEGER(2³²⁻¹ vs 2⁵³), sehingga Anda harus menggunakannya dengan hati-hati!
le_m
@IsmaelMiguel Yo Saya baru saja mencoba metode Anda di konsol dan secara acak mendapat nilai negatif! Math.randRange = (minimum, maksimum) => (Math.random () * (maksimum - minimum + 1)) << 0 Math.randRange (2.657348096152) -1407373159
bluejayke
@bluejayke Karena 657348096152 (1001100100001100111111111111000010011000 dalam biner) memiliki 40 bit, sedangkan aritmatika bitwise menggunakan 32 bit. Jika Anda melakukannya, 657348096152|0Anda mendapatkan 218099864 (1100111111111111000010011000 dalam biner).
Ismael Miguel
1
Ini jawaban yang cerdas. Membuat rentang [min, maks + 1) internal benar-benar mencapai hasil yang diinginkan dari [min, maks] keduanya inklusif. Terima kasih! :)
Mladen B.
135

Math.random ()

Mengembalikan angka acak bilangan bulat antara min ( termasuk ) dan maks ( termasuk ):

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

Atau angka acak antara min ( termasuk ) dan maks ( tidak termasuk ):

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

Contoh berguna (bilangan bulat):

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

** Dan selalu senang diingatkan (Mozilla):

Math.random () tidak memberikan nomor acak yang aman secara kriptografis. Jangan menggunakannya untuk apa pun yang terkait dengan keamanan. Gunakan API Crypto Web sebagai gantinya, dan lebih tepatnya metode window.crypto.getRandomValues ​​().

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

pemakaian:

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.
}

kerusakan:

Kami mengembalikan fungsi (meminjam dari pemrograman fungsional) yang ketika dipanggil, akan mengembalikan integer acak antara nilai-nilai bottomdan top, inklusif. Kami mengatakan 'inklusif' karena kami ingin memasukkan bagian bawah dan atas dalam kisaran angka yang dapat dikembalikan. Cara ini,getRandomizer( 1, 6 ) akan mengembalikan 1, 2, 3, 4, 5, atau 6.

(bawah adalah angka yang lebih rendah, atas adalah jumlah yang lebih besar)

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

Math.random()mengembalikan ganda acak antara 0 dan 1, dan jika kita mengalikannya dengan satu ditambah perbedaan antara topdan bottom, kita akan mendapatkan ganda di antara 0dan 1+b-a.

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

Math.floormembulatkan angka ke bilangan bulat terdekat. Jadi sekarang kita memiliki semua bilangan bulat antara 0dan top-bottom. Angka 1 terlihat membingungkan, tetapi harus ada di sana karena kita selalu dibulatkan ke bawah, sehingga angka teratas tidak akan pernah tercapai tanpa itu. The desimal acak kita menghasilkan kebutuhan untuk berada di kisaran 0ke (1+top-bottom)sehingga kita dapat menggenapkan ke bawah dan mendapatkan int dalam kisaran 0untuktop-bottom

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

Kode pada contoh sebelumnya memberi kita integer dalam range 0dan top-bottom, jadi yang perlu kita lakukan sekarang adalah menambah bottomhasil itu untuk mendapatkan integer dalam range bottomdan topinklusif. : D


CATATAN: Jika Anda memberikan nilai non-integer atau angka yang lebih besar terlebih dahulu Anda akan mendapatkan perilaku yang tidak diinginkan, tetapi kecuali ada yang memintanya, saya tidak akan menyelidiki kode pemeriksaan argumen karena agak jauh dari maksud pertanyaan aslinya .

Gordon Gustafson
sumber
1
Saya menyadari ini sekitar 2½ tahun kemudian, tetapi dengan input 1 dan 6 fungsi Anda mengembalikan nilai 1,2,3,4 dan 5, tetapi tidak pernah 6, seperti jika "inklusif".
beberapa
9
@Beberapa, Bisa jadi lebih buruk, saya 2½ tahun + 1 hari kemudian ^^
ajax333221
+1, saya menguji kode Anda, tampaknya membuat nilai yang benar. Struktur kreatif untuk menangani skenario tetap yang mungkin akan banyak diulang dalam kode.
Chris
Mengapa Anda memiliki fungsi dalam fungsi ini?
Alph.Dev
1
@ Alph.Dev Untuk memisahkan logika yang menggunakan generator angka acak dari logika yang menentukan dengan tepat distribusi nomor acak apa yang akan digunakan. Ketika kode yang menggunakan generator angka acak menerimanya sebagai parameter (fungsi 0-argumen yang selalu mengembalikan nomor acak baru), kode itu dapat bekerja dengan segala jenis generator nomor acak.
Gordon Gustafson
31
function randomRange(min, max) {
  return ~~(Math.random() * (max - min + 1)) + min
}

Alternatif jika Anda menggunakan Underscore.js yang dapat Anda gunakan

_.random(min, max)
Codler
sumber
1
Garis bawah sebenarnya menyediakan _.uniqueId()fungsi yang dapat Anda panggil untuk model sisi klien.
obfk
Menggunakan operator biner ( x << 0, x | 0, ~~x) bukannya Math.floor()bertobat xmenjadi dua pelengkap dengan berbagai jauh lebih kecil dari Number.MAX_SAFE_INTEGER(2³²⁻¹ vs 2⁵³), sehingga Anda harus menggunakannya dengan hati-hati!
le_m
31

Kembalikan angka acak antara 1 dan 10:

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

Kembalikan angka acak antara 1 dan 100:

Math.floor((Math.random()*100) + 1)
Prasobh.Kollattu
sumber
Apakah "antara" Anda inklusif atau eksklusif? yaitu apakah [1,10], [1,10), (1,10], atau (1,10)?
evandrix
1
Ini termasuk sebagian: [1, *)
Ivan Z
apa perlunya +1 di akhir fungsi? Kurasa itu berfungsi dengan baik.
Shachi
18

Jika Anda membutuhkan variabel antara 0 dan maks, Anda dapat menggunakan:

Math.floor(Math.random() *  max);
Stanislav Vincent
sumber
Apakah maks inklusif atau eksklusif?
Pohon
2
@Tree menggunakan Math.floor max eksklusif. Jika Anda ingin maks untuk menjadi inklusif Anda bisa menggunakan Math.round.
Lukas
14

Jawaban lain tidak menjelaskan parameter masuk akal 0dan masuk akal 1. Sebaliknya Anda harus menggunakan round bukan dari ceilatau 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
Starkers
sumber
1
Jawaban Anda benar tetapi saya pikir contoh Anda salah .. console.log(randomNumber(5,6)); # 9 6 6 5 7 7Apakah 9 & 7 datang antara 5 & 6? ...... Anda harus memperbaikinya atau menjelaskan ..
Sachin
12

Berikut ini adalah Implementasi MS DotNet dari kelas Acak di 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;
}());

Menggunakan:

        var r = new Random();
        var nextInt = r.Next(1, 100); //returns an integer between range
        var nextDbl = r.NextDouble(); //returns a random decimal
Islam yang penuh arti
sumber
Kelas MS DotNet Random berada di bawah lisensi Ms-RSL , yang berarti memiliki hak cipta. Jadi berhati-hatilah saat menggunakan kode turunan ini, karena ini dapat menjadi landasan bagi kasus pelanggaran hak cipta.
JohannesB
12

Gunakan fungsi ini untuk mendapatkan angka acak antara rentang yang diberikan

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

Setelah menghasilkan nomor acak menggunakan program komputer, itu masih dianggap sebagai nomor acak jika nomor yang dipilih adalah bagian atau penuh dari yang awal. Tetapi jika itu diubah, maka matematikawan tidak menerimanya sebagai angka acak dan mereka dapat menyebutnya angka bias. Tetapi jika Anda sedang mengembangkan program untuk tugas sederhana, ini tidak akan menjadi kasus untuk dipertimbangkan. Tetapi jika Anda mengembangkan suatu program untuk menghasilkan angka acak untuk hal-hal berharga seperti program lotere, atau permainan judi, maka program Anda akan ditolak oleh manajemen jika Anda tidak mempertimbangkan tentang kasus di atas.

Jadi untuk orang-orang seperti itu, inilah saran saya:

Hasilkan nomor acak menggunakan Math.random() . (Katakan ini 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.

Jika Anda tahu cara membaca tabel angka acak untuk memilih angka acak, Anda tahu proses di atas (dikalikan dengan 1, 10, 100 dan seterusnya) tidak melanggar salah satu yang saya sebutkan di awal. (Karena hanya mengubah tempat titik desimal.)

Pelajari contoh berikut dan kembangkan sesuai kebutuhan Anda.

Jika Anda membutuhkan sampel [0,9] maka lantai n * 10 adalah jawaban Anda dan jika perlu [0,99] maka lantai n * 100 adalah jawaban Anda dan seterusnya.

Sekarang, mari masuk ke dalam peran Anda:

Anda telah menanyakan nomor di antara rentang tertentu. (Dalam hal ini Anda bias di antara rentang itu. - Dengan mengambil angka dari [1,6] dengan menggulung dadu, maka Anda bias menjadi [1,6] tapi tetap saja itu acak jika dan hanya jika dadu tidak bias .)

Jadi pertimbangkan kisaran Anda ==> [78, 247] jumlah elemen rentang = 247 - 78 + 1 = 170; (karena kedua batas inklusif.

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

Catatan: Di metode satu, pertama saya membuat array yang berisi angka yang Anda butuhkan dan kemudian secara acak memasukkannya ke array lain. Dalam metode dua, hasilkan angka secara acak dan periksa apakah ada dalam kisaran yang Anda butuhkan. Lalu masukkan ke dalam array. Di sini saya menghasilkan dua angka acak dan menggunakan totalnya untuk memaksimalkan kecepatan program dengan meminimalkan tingkat kegagalan yang memperoleh angka yang bermanfaat. Namun menambahkan angka yang dihasilkan juga akan memberikan sedikit kecocokan. Jadi saya akan merekomendasikan metode pertama saya untuk menghasilkan angka acak dalam rentang tertentu.

Dalam kedua metode, konsol Anda akan menunjukkan hasilnya. (Tekan f12 di Chrome untuk membuka konsol)

Janaka R Rajapaksha
sumber
3
"acak" tidak selalu berarti "didistribusikan secara seragam". "bias" tidak menyiratkan "non-acak". cara acak diambil dari distribusi probabilitas.
syzygy
6
Hampir tidak bisa mengatakan apa yang coba dikatakan jawaban ini. Namun, jika Anda memerlukan angka acak untuk penggunaan seperti angka lotre dan perjudian. Pertama, Anda mungkin seharusnya tidak membuatnya di klien. Kedua, Anda memerlukan generator nomor acak yang aman secara kriptografis dan algo yang disediakan tidak cukup. Memanggil acak berulang kali tidak menjadikan hasil "lebih acak". Penulis tampaknya prihatin dengan bias, tetapi tidak memberikan algo yang baik untuk mencegahnya. Faktanya, jawaban singkat lain yang disediakan menghasilkan angka acak yang tidak bias (dengan asumsi generator acak yang mendasarinya tidak bias).
Jeff Walker Code Ranger
@JeffWalkerCodeRanger Saya pikir apa yang dia maksudkan adalah bahwa dengan algoritma "normal" [yaitu Math.floor(Math.random() * (6 - 1 + 1) + 1)] angka 1 dan 6 akan selalu digulirkan lebih sedikit dari 2, 3, 4, dan 5. Namun, perbedaannya pada dasarnya tidak signifikan.
oldboy
10

Untuk bilangan bulat acak dengan rentang, coba:

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;
}
pengguna1764199
sumber
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)));
}

Untuk menguji fungsi ini, dan variasi fungsi ini, simpan HTML / JavaScript di bawah ini ke file dan buka dengan browser. Kode akan menghasilkan grafik yang menunjukkan distribusi satu juta panggilan fungsi. Kode juga akan merekam kasus tepi, jadi jika fungsi menghasilkan nilai lebih besar dari maks, atau kurang dari min, Anda.will.know.about.it.

<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>
Chris
sumber
7

Untuk mendapatkan nomor acak katakan antara 1 dan 6, pertama lakukan:

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

Ini mengalikan angka acak dengan 6 dan kemudian menambahkan 0,5 ke dalamnya. Selanjutnya bulatkan angka ke bilangan bulat positif dengan melakukan:

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

Ini membulatkan angka ke seluruh nomor terdekat.

Atau untuk membuatnya lebih dimengerti lakukan ini:

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

Secara umum kode untuk melakukan ini menggunakan variabel adalah:

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

Alasan untuk mengambil 0,5 dari nilai minimum adalah karena menggunakan nilai minimum saja akan memungkinkan Anda untuk mendapatkan bilangan bulat yang satu lebih dari nilai maksimum Anda. Dengan mengambil 0,5 dari nilai minimum Anda pada dasarnya mencegah nilai maksimum dibulatkan.

Semoga itu bisa membantu.

Learner.js
sumber
Masuk akal jika Anda mengecualikan 0 , maka tidak perlu "bulatkan" berkisar dari 0 hingga 0,5.
ILMostro_7
7

Menggunakan kode berikut Anda dapat menghasilkan array angka acak, tanpa berulang, dalam rentang yang diberikan.

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;
        }
Yusuf
sumber
7

Saya tahu pertanyaan ini sudah dijawab tetapi jawaban saya dapat membantu seseorang.

Saya menemukan metode sederhana ini di W3Schools:

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

Semoga ini bisa membantu seseorang.

Alat pemecah buah keras
sumber
1
Math.floor ((Math.random () * 1) + 0); selalu memberikan 0
madprops
1
@madprops Karena nomor maks eksklusif. Untuk mendapatkan 0 atau 1, Anda harus menetapkan 2 sebagai angka maksimal.
NutCracker
1
atau Anda hanya menambahkan +1 pada fungsi yang memanggil metode ini
Pietro Coelho
6

Seluruh angka acak antara terendah dan tertinggi:

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

Bukan solusi yang paling elegan .. tapi sesuatu yang cepat.

brooklynsweb
sumber
5

Inilah yang saya gunakan untuk menghasilkan angka acak.

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

Kami mengeksekusi high++karenaMath.random() menghasilkan angka acak antara 0, (termasuk), dan 1 (eksklusif) Yang dikecualikan, berarti kami harus menambah tinggi dengan satu sebelum mengeksekusi matematika apa pun. Kami kemudian mengurangi rendah dari tinggi, memberi kami angka tertinggi untuk menghasilkan - rendah, lalu + rendah, membawa tinggi kembali ke normal, dan membuat angka terendah minimal rendah. lalu kami kembalikan nomor yang dihasilkan

random(7,3) bisa kembali 3,4,5,6, or 7

Travis
sumber
2
Karena highhanya digunakan satu kali, Anda sebaiknya menggunakan high-low+1daripada memiliki pernyataan kenaikan yang terpisah. Juga, sebagian besar pengguna akan mengharapkan lowparameter menjadi yang utama.
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 membuat array yang diisi dengan angka hingga 3 digit yang akan menjadi maksimum 999. Kode ini sangat pendek.

senang
sumber
4

Berikut adalah contoh fungsi javascript yang dapat menghasilkan angka acak dari panjang yang ditentukan tanpa menggunakan 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;
    }
Nilesh Pawar
sumber
t1 / t2 selalu sangat dekat dengan 1. dan karenanya fungsi Anda mengembalikan angka yang sama ketika fungsi disebut berulang .. jsbin.com/xogufacera/edit?js,console
Sunil BN
periksa urs jsbin .. Anda akan melihat hasilnya sendiri
Sunil BN
Ini bekerja dengan baik ketika panjangnya antara 4-10 (Seperti yang saya uji pada mesin saya), karena nilai konstanta T1 & T2 harus memiliki jarak yang sesuai.
Nilesh Pawar
3

ini adalah pendapat saya tentang bilangan acak dalam suatu rentang, karena saya ingin mendapatkan bilangan acak dalam rentang basis untuk eksponen. mis. basis = 10, eksponen = 2, memberikan angka acak dari 0 hingga 100, idealnya, dan seterusnya.

jika itu membantu menggunakannya, ini dia:

// 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);
Goran B.
sumber
3

Math.random() cepat dan cocok untuk banyak tujuan, tetapi tidak tepat jika Anda membutuhkan nilai-nilai yang aman secara kriptografis (tidak aman), atau jika Anda memerlukan bilangan bulat dari distribusi yang sama sekali tidak bias (pendekatan multiplikasi yang digunakan dalam jawaban lain menghasilkan nilai-nilai tertentu sedikit lebih sering lebih sering dari yang lain).

Dalam kasus seperti itu, kita bisa menggunakan crypto.getRandomValues() untuk menghasilkan integer aman, dan menolak nilai apa pun yang dihasilkan yang tidak dapat dipetakan secara seragam ke dalam rentang target. Ini akan lebih lambat, tetapi seharusnya tidak signifikan kecuali Anda menghasilkan nilai yang sangat besar.

Untuk memperjelas masalah distribusi bias, pertimbangkan kasus di mana kami ingin menghasilkan nilai antara 1 dan 5, tetapi kami memiliki generator angka acak yang menghasilkan nilai antara 1 dan 16 (nilai 4-bit). Kami ingin memiliki jumlah yang sama dari pemetaan nilai yang dihasilkan untuk setiap nilai output, tetapi 16 tidak dibagi rata dengan 5: ia meninggalkan sisa dari 1. Jadi kita perlu menolak 1 dari nilai yang mungkin dihasilkan, dan hanya melanjutkan ketika kita mendapatkan salah satu dari 15 nilai lebih rendah yang dapat dipetakan secara seragam ke dalam kisaran target kami. Perilaku kita bisa terlihat seperti kodesemu ini:

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.

Kode berikut menggunakan logika yang sama, tetapi menghasilkan bilangan bulat 32-bit sebagai gantinya, karena itulah ukuran bilangan bulat umum terbesar yang dapat diwakili oleh numbertipe standar JavaScript . (Ini dapat dimodifikasi untuk menggunakan BigInts jika Anda membutuhkan rentang yang lebih besar.) Terlepas dari rentang yang dipilih, fraksi dari nilai yang dihasilkan akan selalu kurang dari 0,5, sehingga jumlah penolakan yang diharapkan akan selalu kurang dari 1,0 dan biasanya mendekati 0,0; Anda tidak perlu khawatir tentang hal itu berulang selamanya.

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]

Jeremy Banks
sumber
3

Crypto-Strong

Untuk mendapatkan angka integer acak crypto-kuat dalam ragne [x, y] coba

let cs= (x,y)=>x+(y-x+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log(cs(4,8))

Kamil Kiełczewski
sumber
4
yang ini menarik
Akin Hwan
1

Anda dapat memberi Anda potongan kode ini,

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;
}
Achintha Isuru
sumber
1
Ada garis duplikasi yang tidak perlu di sini. Cukup gunakan do - whilesebagai gantiwhile
Javi Marzán
1

Ionuț G. Stan menulis jawaban yang bagus tetapi agak terlalu rumit untuk saya pahami. Jadi, saya menemukan penjelasan yang lebih sederhana dari konsep yang sama di https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1-min-explanation oleh Jason Anello.

CATATAN: Satu-satunya hal penting yang harus Anda ketahui sebelum membaca penjelasan Jason adalah definisi "truncate". Dia menggunakan istilah itu saat menggambarkan Math.floor(). Kamus Oxford mendefinisikan "truncate" sebagai:

Persingkat (sesuatu) dengan memotong bagian atas atau ujung.

Dani Amsalem
sumber
0

Ini dapat menangani menghasilkan hingga 20 digit nomor acak UNIK

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

masukkan deskripsi gambar di sini

JsFiddle

Nofi
sumber
Saya membatalkan ini hanya karena.
Taylor Ackley
1
@TaylorAckley Jawaban ini tidak menjawab pertanyaan.
RomainValeri
0

/ * Tulis fungsi yang disebut randUpToyang menerima angka dan mengembalikan bilangan bulat acak antara 0 dan angka itu? * /

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

/ * Tulis fungsi yang dipanggil randBetweenyang menerima dua angka yang mewakili suatu rentang dan mengembalikan seluruh angka acak di antara kedua angka itu. * /

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

/ * Tulis fungsi yang dipanggil randFromTillyang menerima dua angka yang mewakili rentang dan mengembalikan angka acak antara min (inklusif) dan maks (eksklusif). * /

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

/ * Tulis fungsi yang dipanggil randFromToyang menerima dua angka yang mewakili rentang dan mengembalikan bilangan bulat acak antara min (inklusif) dan maks (inklusif) * /

var randFromTo = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
};
Prakhar Mittal
sumber
1
Cantik, dapatkah Anda juga mencatat bahwa randBetween adalah (eksklusif) (eksklusif)?
pfdint
0

Saya membuat fungsi ini yang mempertimbangkan opsi akun seperti min, max, mengecualikan (daftar int untuk dikecualikan), dan seed (jika Anda ingin generator acak diunggulkan).

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
}

Dapat digunakan seperti:

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

Atau lebih sederhana:

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

Maka Anda dapat melakukan:

let item = some_list[n]

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

madprops
sumber
0
  • acak (min, maks) menghasilkan angka acak antara min (inklusif) dan maks (eksklusif)
  • Math.floor membulatkan angka ke bilangan bulat terdekat

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

Jadi untuk menghasilkan bilangan bulat acak antara 4 dan 8 inklusif, panggil fungsi di atas dengan argumen berikut:

generateRandomInteger (4,9)
Orang Normandia
sumber
0

Metode saya menghasilkan angka acak antara 0 dan n, di mana n <= 10 (n dikecualikan):

Math.floor((Math.random() * 10) % n)
Nitin Jadhav
sumber