JavaScript'te iki sayı arasında rastgele sayı oluşturma


1796

JavaScript'te belirli bir aralıkta (örn. 1 ile 6: 1, 2, 3, 4, 5 veya 6) rastgele bir sayı oluşturmanın bir yolu var mı?


12
Math.floor (Math.random () * 7)
Amjad Masad

65
Tabii .. Math.floor (Math.random () * 6 + 1)
Amjad Masad

3
Nabil Kadimi de negatif rastgele sayıların nasıl üretileceğine dair bir makale yazdı .
madc

İşte yararlı bir öz
Dan KK

Neden böyle bir çözüm Math.floor((Math.random()*10)+1);burada w3schools.com/jsref/jsref_random.asp .. adresinde belirtildiği gibi sizin için çalışmıyor ?
shashwat

Yanıtlar:


2115

Önemli

Aşağıdaki kod yalnızca minimum değer olduğunda çalışır 1. Bunun dışındaki minimum değerler için çalışmaz 1.

1 ( ve yalnızca 1 ) ile 6 arasında rastgele bir tamsayı almak istiyorsanız, şunu hesaplarsınız:

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

Nerede:

  • 1 başlangıç ​​numarasıdır
  • 6 olası sonuç sayısıdır (1 + başlangıç (6) - bitiş (1) )

45
Bu işe yarar, @Mike, Francisc'in aşağıda olduğu gibi daha genel bir versiyona işaret etmek en iyisi olacaktır :-).
Raymond Machira

58
-1. Google'ı aradıktan sonra bu soruyu buldum, başlık "" Javascript'te iki sayı arasında rasgele değer oluştur ". Min değeri 0 ise işe yaramaz
Ydhem

18
İki büyük sayı arasında bir sayı istiyorsanız, örneğin çalışmaz. Math.floor (Math.random () * 900) + 700
Rob

14
Bu sadece minimum 1 ise işe yarar. Eğer min 2 ise ve yine de kullanırsak Math.floor(Math.random() * 6) + 2, Math.random()sonuçlar 0.99'a kadar olursa rastgele değerimiz7
antitoksik 12.12 '

27
Bu kod iyi değil çünkü herhangi bir sayı ile çalışmaz. @Francisc kodu doğrudur.
Lion King

2283
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

"Ekstra" özelliği, 1 ile başlamayan rastgele aralıklara izin vermesidir. Böylece örneğin 10'dan 15'e kadar rastgele bir sayı elde edebilirsiniz. Esneklik.


5
bu da harika çünkü birisi toarg'u içermezse, fromarg max olarak iki katına çıkar
Jason

12
Merhaba. Bu MDN'yi dan: Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range.( developer.mozilla.org/en-US/docs/JavaScript/Reference/... )
Francisc

5
Yukarıdaki yorumu okuyun. Rastgele [0,1] değil, [0,1) içindedir.
Francisc

3
Küçük sayı 0 ise büyük İşleri
Robin Zimmermann

2
Bu çözümün yalnızca min ve maks tamsayılar olduğunda doğru olduğunu unutmayın, aksi takdirde [min, tavan (max)] aralığında bir sonuç alabilirsiniz. Yani aralık dışında bir sonuç elde edebilirsiniz, çünkü maks.
collimarco

326

Math.random ()

Min ( dahil ) ile max ( dahil ) arasında bir tamsayı rasgele sayı döndürür :

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

Veya min ( dahil ) ve max ( dahil değil ) arasındaki herhangi bir rastgele sayı :

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

Yararlı örnekler (tamsayılar):

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

** Ve her zaman hatırlatılması güzel (Mozilla):

Math.random () şifreli olarak güvenli rasgele sayılar sağlamaz. Bunları güvenlikle ilgili hiçbir şey için kullanmayın. Bunun yerine Web Kripto API'sını ve daha doğrusu window.crypto.getRandomValues ​​() yöntemini kullanın.


Beni karıştıran bir şey ... Math.floor (..), sayının Math.round (..) 'un eşit olmayan bir dağılım vereceği bir tamsayı olmasını sağlar. Ref: developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/…
alikuli

1
Bu cevaba güveniyorum. Herkes bunun neden çalıştığına dair bir bağlantı veya açık bir açıklama verebilir mi? Belki de Math.round'un nasıl önyargı vereceğine bir örnek ve bunun neden bu oldukça karmaşık görünen formülü kullanmamız gerektiği anlamına geliyor?
Robin Andrews

6
@alikuli bir dizi için [1,2],% 25 şans var Math.random()bunlardan birinden bir numara verecek [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Bu aralıkların yuvarlanması eşit dağılım olmayan 0, 1, 1, 2 ile sonuçlanır. Döşeme onları 0, 0, 1, 1 ile
sonuçlanır

1
@shuji Bu , diğerlerinin yanı sıra, doğru cevaptır. Sadece kullanarak neden açıklamak istedik Math.roundüzerinde Math.floorfarklı sonuçlar verecekti.
pishpish

Bulduğum en doğru çözüm: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik

91

Diğer çözümler:

  • (Math.random() * 6 | 0) + 1
  • ~~(Math.random() * 6) + 1

Çevrimiçi deneyin


6
~~ sintaksiyi açıklamak (veya bunlara referanslar vermek) ister misiniz? Daha önce görmedim! Zarif çözüm ama anlaşılması zor.
DiegoDD

27
Double Tilde ~~a ve Bitwise OR (a | 0),
Math.floor

7
a | 0aynı zamanda bir dizgiyi tamsayıya dönüştürmenin en hızlı ve en iyileştirilmiş yoludur. Yalnızca tamsayı ( "444"ve "-444") içeren dizelerle çalışır , yani kayan nokta / kesir içermez. 0Başarısız olan her şey için bir a verir . Asm.js arkasında ana optimizasyon biridir.
pilau

3
Not: Eğer gerçekten çok büyük sayılarla çalışıyorsanız, çift tilde çalışmaz. Deneyin ~~(Math.random() * (50000000000000 - 0 + 1)) + 0veMath.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM

3
"Çift tilde ve bitsel VEYA / Matematik nokta zemin yazmak için daha hızlı yollardır" benim sabah aydınlatan güzel bir kafiye beyit. Teşekkürler @ edi9999!
teedyay

60

TL; DR

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

Rastgele sayı almak için generateRandomInteger(-20, 20);

AŞAĞIDAKİ AÇIKLAMA

Biz rastgele bir tamsayı olsun demek gerekir X minimum ve maksimum arasında.

Sağ?

yani min <= X <= maks

Denklemden min çıkarırsak, bu eşittir

0 <= (X - dak) <= (maks - dak)

Şimdi, bir rastgele sayı ile çarpın bu olanak r olduğunu

0 <= (X - dak) * r <= (maks - dak) * r

Şimdi, denkleme min ekleyelim

min <= min + (X - min) * r <= min + (max - min) * r

Şimdi, r ile sonuçlanan, [min, maks] denklem aralığımızı karşılayacak bir fonksiyon seçelim. Bu sadece 0 <= r <= 1 ise mümkündür

TAMAM. Şimdi, r yani [0,1] aralığı Math.random () fonksiyon sonucuna çok benzer. Öyle değil mi?

Math.random () işlevi, [0, 1) aralığında kayan noktalı, sahte rasgele bir sayı döndürür; yani 0 (dahil) ile 1 (hariç) arasında

Örneğin,

Durum r = 0

min+ 0 * ( max- min) = dk.

Durum r = 1

min+ 1 * ( max- min) = maks.

Math.random 0 <= r <1 kullanan Rastgele Durum

min+ r * ( max- min) = X ; burada X , min <= X < maks aralığına sahiptir

Yukarıdaki X sonucu rastgele bir sayısaldır. Ancak Math.random () nedeniyle sol sınırımız kapsayıcıdır ve sağ sınır münhasırdır. Sağ sınırımızı dahil etmek için sağ sınırı 1 arttırır ve sonucu ortaya koyarız.

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

Rastgele sayı almak için

generateRandomInteger(-20, 20);



24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;

2
Aslında. Rand 0 dahil olduğunu unuttum. Onu düzeltti.
ryebr3ad

3
Bu Pseudocode'un bir parçası ... biri gerçek olduğunu düşünebilir ve böyle kullanmaya çalışabilir.
gravityboy

35
@gravityboy Neden bahsediyorsun? Birisi [sayı seç ...] yerine bir sayı koyamazsa, programcı olarak uygun olmayabilir.
ryebr3ad

7
@ ryebr3ad -1! javascript'te sahte kodda değil ve aynı zamanda tüm okuyucuların başarılı programcılar olmadığı söylenir. Çoğu yeni başlayanlar!
Steve

3
@ ryebr3ad: Stajyerlere desteğe ihtiyaç duyacakları bir stajyer öğreten bir iş arkadaşım vardı. Onlara her şeyi bir tablodan seçmelerini söyledi ve doğrudan SQL sorgu düzenleyicisine "... dışında her şeyi seç" yazmaya başladılar. Seninle aynı tepkiyi verdi.
Ellesedil

22

jsfiddle: https://jsfiddle.net/cyGwf/477/

Rastgele Tamsayı : arasında rasgele bir sayı elde etmek minve maxaşağıdaki kodu kullanın

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

Rastgele serbest noktası sayısı : arasında rastgele kayan nokta numarası almak için minve maxşu kodu kullanın,

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

Referans: https://developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/Global_Objects/Math/random


14

Matematik benim güçlü yanım değil, ama hem pozitif hem de negatif arasında çok sayıda rastgele sayı üretmem gereken bir proje üzerinde çalışıyorum.

function randomBetween(min, max) {
    if (min < 0) {
        return min + Math.random() * (Math.abs(min)+max);
    }else {
        return min + Math.random() * max;
    }
}

Örneğin

randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)

Elbette, bunu sayılardan başka bir şeyle yapmadığınızdan emin olmak için bir miktar doğrulama da ekleyebilirsiniz. Ayrıca min'in her zaman maks.


5
Bu sadece yanlış. min + Math.random() * maxsize min ve min + max arasında rakamlar verecektir, bu istediğiniz değildir. İlk dalı ifdoğrudur, ancak min'in return min + Math.random() * (max - min)pozitif veya negatif olup olmadığına bakılmaksızın doğru çözüm olduğunu söylemek basitleştirilebilir (diğer cevaplara bakın). Ayrıca, kesir istemiyorsanız yine de sonucu katlamanız gerektiğini unutmayın.
Avish

10

Size sadece tamsayı değil, rastgele sayı verebilecek daha esnek bir işlev yazdım.

function rand(min,max,interval)
{
    if (typeof(interval)==='undefined') interval = 1;
    var r = Math.floor(Math.random()*(max-min+interval)/interval);
    return r*interval+min;
}

var a = rand(0,10); //can be 0, 1, 2 (...) 9, 10
var b = rand(4,6,0.1); //can be 4.0, 4.1, 4.2 (...) 5.9, 6.0

Sabit sürüm.


Min değeri olarak sıfır ile çalışmadığından bu iyi bir çözüm değildir. Bakınız @ Lior'un cevabı.
Sebastien

Tabii ki min değeri olarak sıfır ile çalışır. Denedin mi? Çalışmamasının bir nedeni yoktur. Garip olmayan aralık olarak 0 ile çalışmaz (aralık = 0? ...).
ElChupacabra

Bu işlevi, min değeri olarak sıfır ile birden çok kez çalıştırdım ve çıkışta sıfır elde etmedim. Yoksa yeterince şanslı değilim ...
Sebastien

Haklısın. "+ aralık" yanlış yerdeydi. Şimdi test edin lütfen. Bazen console.log bana 0.3 yerine 3 * 0.1 yerine 0.300000004 veren garip bir şey tam olarak 0.3 olmaz.
ElChupacabra

9

Misal

1 ile 10 arasında rastgele bir sayı döndürün:

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

Sonuç şu olabilir: 3

Kendiniz deneyin: burada

-

veya lodash / undescore kullanarak:

_.random(min, max)

Dokümanlar: - lodash - undescore


1
yani 9 ya da 10'a ihtiyacınız var değil mi? Evet ise: const randomNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber% 2 === 0? 9: 10
Sebastián Lara

7

Birçok cevabı ve neredeyse aynı sonucu inceleyin. Cevabımı eklemek ve çalışmasını açıklamak istiyorum. Çünkü bir satır kodunu kopyalamak yerine çalışmasını anlamak önemlidir. Rastgele sayılar üretmek basit matematikten başka bir şey değildir.

KODU:

function getR(lower, upper) {

  var percent = (Math.random() * 100);
  // this will return number between 0-99 because Math.random returns decimal number from 0-0.9929292 something like that
  //now you have a percentage, use it find out the number between your INTERVAL :upper-lower 
  var num = ((percent * (upper - lower) / 100));
  //num will now have a number that falls in your INTERVAL simple maths
  num += lower;
  //add lower to make it fall in your INTERVAL
  //but num is still in decimal
  //use Math.floor>downward to its nearest integer you won't get upper value ever
  //use Math.ceil>upward to its nearest integer upper value is possible
  //Math.round>to its nearest integer 2.4>2 2.5>3   both lower and upper value possible
  console.log(Math.floor(num), Math.ceil(num), Math.round(num));
}

6

TypeScript'te yazılmış rasgele sayı üretecini araştırıyordum ve tüm cevapları okuduktan sonra bunu yazdım, umarım TypeScript kodlayıcıları için çalışır.

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   

5

Math.random() birçok amaç için hızlı ve uygundur, ancak kriptografik olarak güvenli değerlere ihtiyacınız varsa (güvenli değildir) veya tamamen tekdüze bir tarafsız dağıtımdan tamsayılara ihtiyacınız varsa (başkalarının cevaplarında kullanılan çarpma yaklaşımı biraz daha sık belirli değerler üretir) diğerlerine göre).

Bu gibi durumlarda, crypto.getRandomValues()güvenli tamsayılar oluşturmak ve hedef aralığa eşit olarak eşleştiremediğimiz oluşturulan değerleri reddetmek için kullanabiliriz. Bu daha yavaş olacaktır, ancak çok fazla değer üretmediğiniz sürece önemli olmamalıdır.

Önyargılı dağıtım endişesini açıklığa kavuşturmak için, 1 ile 5 arasında bir değer üretmek istediğimiz durumu düşünün, ancak 1 ile 16 arasında değerler üreten bir rastgele sayı üretecimiz var (4 bitlik bir değer). Her bir çıkış değeri ile aynı sayıda üretilen değere eşleme yapmak istiyoruz, ancak 16 eşit olarak 5'e bölünmüyor: 1'in geri kalanını bırakıyor. Bu nedenle, olası üretilen değerlerin 1'ini reddetmeliyiz ve yalnızca hedef aralığımıza eşit olarak eşlenebilen 15 küçük değerden biri. Davranışımız şu sahte kod gibi görünebilir:

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.

Aşağıdaki kod benzer mantık kullanır, ancak bunun yerine 32 bitlik bir tamsayı oluşturur, çünkü bu, JavaScript'in standart numbertürüyle temsil edilebilecek en büyük ortak tamsayı boyutudur . (Bu, BigIntdaha geniş bir aralığa ihtiyacınız varsa s kullanmak için değiştirilebilir .) Seçilen aralığa bakılmaksızın, reddedilen üretilen değerlerin oranı her zaman 0,5'ten az olur, bu nedenle beklenen reddetme sayısı her zaman 1,0'dan az olur ve genellikle 0.0'a yakın; sonsuza kadar döngü hakkında endişelenmenize gerek yok.

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]


Şimdi, buna aşırı yüklenme diyorum.
2xSamurai

2
@ 2xSamurai Burada, neden buna ihtiyaç duyabileceğinizi ve nasıl çalıştığını açıklamak için cevabı güncelledim. Bu daha iyi mi? : P
Jeremy Banks

Kriptografik olarak güvenli ve eşit olarak dağıtılmış rasgele sayılar istiyorsanız, bu aşırı bir ölüm değildir. Bu gereksinimleri karşılayan rastgele sayılar üretmek zordur. Harika cevap, @ JererBanks.
thomaskonrad

4

@ Francisc'in cevabındaki floatversiyona dayalı sabit hassas versiyon ile ekleme int:

function randomFloatFromInterval (min, max, fractionDigits) {
  const fractionMultiplier = Math.pow(10, fractionDigits)
  return Math.round(
    (Math.random() * (max - min) + min) * fractionMultiplier,
  ) / fractionMultiplier
}

yani:

randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...

ve int cevap için

randomFloatFromInterval(1,3,0) // => 1, 2, 3


1

Bu çalışmalı:

const getRandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min

1

ES6 varsayılan parametrelerini kullanarak bunu yapmanın yeni ve harika bir yolunu keşfettim. Bir veya iki argümana izin verdiği için çok şıktır. İşte burada:

function random(n, b = 0) {
    return Math.random() * (b-n) + n;
}

1

Bu yaklaşık dokuz yıl gecikti, ancak randojs.com bunu basit bir tek astar yapıyor:

rando(1, 6)

Bunu html belgenizin başına eklemeniz yeterlidir ve rasgele bir şekilde istediğiniz her şeyi kolayca yapabilirsiniz. Dizilerden rastgele değerler, rastgele jquery öğeleri, nesnelerden rastgele özellikler ve hatta gerekirse tekrarları önleme.

<script src="https://randojs.com/1.0.0.js"></script>

Zaten tek katmanlı olan bir şeyi yapmak için neden bağımlılık eklemelisiniz? JS topluluğuna kütüphane ekleme takıntısı çılgınca
Daniel Cooke

okunması ve hatırlanması daha kolay. katılıyorum olsa
Aaron Plocharczyk

1

Bu benim için çalışıyor ve Python'un random.randint standart kütüphane işlevi gibi değerler üretiyor :


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

console.log("Random integer: " + randint(-5, 5));

1

Kullanmayı deneyin:

function random(min, max) {
   return Math.round((Math.random() *( Math.abs(max - min))) + min);
}
console.log(random(1, 6));


1

1-6 zar gibi dönmek,

return Math.round(Math.random() * 5 + 1);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.