JavaScript'te belirtilen iki değişken arasında rastgele tam sayıları nasıl oluşturabilirim, örneğin x = 4
ve y = 8
, 4, 5, 6, 7, 8
den herhangi birini çıkarır?
Mozilla Geliştirici Ağı]1 sayfasında bazı örnekler bulunmaktadır:
/**
* 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;
}
Bunun arkasındaki mantık şu. Bu basit bir üç kuralı:
Math.random()0 (dahil) ile 1 (hariç) arasında bir
Sayı` döndürür. Yani şöyle bir aralığımız var:
[0 .................................... 1)
Şimdi, min
(dahil) ve maks
(hariç) arasında bir sayı istiyoruz:
[0 .................................... 1)
[min .................................. max)
Karşılığı [min, max) aralığında almak için Math.random
kullanabiliriz. Ancak, önce ikinci aralıktan min
i çıkararak problemi biraz çarpanlarına ayırmalıyız:
[0 .................................... 1)
[min - min ............................ max - min)
Bu verir:
[0 .................................... 1)
[0 .................................... max - min)
Şimdi `Math.random' uygulayabilir ve ardından karşılık gelen değeri hesaplayabiliriz. Rastgele bir sayı seçelim:
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
Yani, x
değerini bulmak için şunu yapmalıyız:
x = Math.random() * (max - min);
Min`i geri eklemeyi unutmayın, böylece [min, max) aralığında bir sayı elde ederiz:
x = Math.random() * (max - min) + min;
Bu MDN'nin ilk işleviydi. İkincisi, her ikisi de dahil olmak üzere min
ve maks
arasında bir tamsayı döndürür.
Şimdi tamsayıları almak için round
, ceil
veya floor
kullanabilirsiniz.
Math.round(Math.random() * (max - min)) + minkullanabilirsiniz, ancak bu eşit olmayan bir dağılım verir. Hem
minhem de
maks` sadece yaklaşık olarak yarı yarıya atma şansına sahiptir:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
Maxaralıktan çıkarıldığında,
min`den daha az atma şansı vardır.
Math.floor(Math.random() * (max - min +1)) + min` ile tamamen eşit bir dağılıma sahip olursunuz.
min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
| | | | | |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max
Bu denklemde ceil()
ve -1
kullanamazsınız çünkü max
ın artık biraz daha az atma şansı vardır, ancak (istenmeyen) min-1
sonucunu da atabilirsiniz.
function getRandomizer(bottom, top) {
return function() {
return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
}
}
kullanım:
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.
}
Arıza:
Çağrıldığında alt
ve üst
değerleri arasında rastgele bir tamsayı döndürecek bir fonksiyon (fonksiyonel programlamadan ödünç alıyoruz) döndürüyoruz. Dahil diyoruz çünkü döndürülebilecek sayı aralığına hem alt hem de üst değerleri dahil etmek istiyoruz. Bu şekilde, getRandomizer( 1, 6 )
1, 2, 3, 4, 5 veya 6 değerlerinden birini döndürecektir.
(alttaki küçük sayı, üstteki büyük sayı)
Math.random() * ( 1 + top - bottom )
Math.random()0 ile 1 arasında rastgele bir double döndürür ve bunu bir artı
üstile
altarasındaki farkla çarparsak,
0ile
1+b-a` arasında bir yerde bir double elde ederiz.
Math.floor( Math.random() * ( 1 + top - bottom ) )
Math.floor
sayıyı en yakın tam sayıya yuvarlar. Şimdi 0
ile üst-alt
arasındaki tüm tam sayılara sahibiz. 1 kafa karıştırıcı görünüyor, ancak orada olması gerekiyor çünkü her zaman aşağı yuvarlıyoruz, bu yüzden o olmadan en üst sayıya asla ulaşılamayacak. Ürettiğimiz rastgele ondalık sayının 0
ile (1+üst-alt)
aralığında olması gerekir, böylece aşağı yuvarlayabilir ve 0
ile üst-alt
aralığında bir int elde edebiliriz
Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
Önceki örnekteki kod bize 0
ve üst-alt
aralığında bir tamsayı verdi, şimdi tek yapmamız gereken alt
ve üst
aralığında bir tamsayı elde etmek için bu sonuca alt
eklemek. :D
NOT: Eğer tamsayı olmayan bir değer ya da daha büyük bir sayı girerseniz istenmeyen bir davranışla karşılaşırsınız, ancak kimse talep etmedikçe, orijinal sorunun amacından oldukça uzak olduğu için argüman kontrol koduna girmeyeceğim.
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)));
}
Bu işlevi ve bu işlevin varyasyonlarını test etmek için aşağıdaki HTML/JavaScript'i bir dosyaya kaydedin ve bir tarayıcı ile açın. Kod, bir milyon fonksiyon çağrısının dağılımını gösteren bir grafik üretecektir. Kod ayrıca uç durumları da kaydedecektir, böylece fonksiyon maksimumdan büyük veya minimumdan küçük bir değer üretirse, bundan.haberiniz.olacaktır.
<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"> [' + (i + min - 1) + ']: '+array[i]+'</span> ');
}
document.write('<hr/>');
</script>
</head>
<body>
</body>
</html>