ฉันจะสร้างตัวเลขสุ่มระหว่างทั้งสองตัวแปรที่ระบุใน JavaScript เช่นx = 4
และy = 8
เอาท์พุทจะใด ๆ4, 5, 6, 7, 8
?
ฉันจะสร้างตัวเลขสุ่มระหว่างทั้งสองตัวแปรที่ระบุใน JavaScript เช่นx = 4
และy = 8
เอาท์พุทจะใด ๆ4, 5, 6, 7, 8
?
คำตอบ:
มีตัวอย่างบางส่วนในหน้า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;
}
นี่คือตรรกะที่อยู่เบื้องหลัง มันเป็นกฎง่ายๆสามข้อ:
Math.random()
ส่งคืนค่าNumber
ระหว่าง 0 (รวม) และ 1 (พิเศษ) ดังนั้นเราจึงมีช่วงเวลาเช่นนี้:
[0 .................................... 1)
ตอนนี้เราต้องการหมายเลขระหว่างmin
(รวม) และmax
(พิเศษ):
[0 .................................... 1)
[min .................................. max)
เราสามารถใช้Math.random
เพื่อรับผู้สื่อข่าวในช่วงเวลา [min, max) แต่ก่อนอื่นเราควรคำนึงถึงปัญหาเล็กน้อยโดยการลบออกmin
จากช่วงเวลาที่สอง:
[0 .................................... 1)
[min - min ............................ max - min)
สิ่งนี้ให้:
[0 .................................... 1)
[0 .................................... max - min)
ตอนนี้เราอาจนำไปใช้Math.random
และจากนั้นคำนวณผู้สื่อข่าว ลองเลือกหมายเลขสุ่ม:
Math.random()
|
[0 .................................... 1)
[0 .................................... max - min)
|
x (what we need)
ดังนั้นเพื่อที่จะค้นหาx
เราจะทำ:
x = Math.random() * (max - min);
อย่าลืมเพิ่มmin
กลับเพื่อให้ได้ตัวเลขในช่วง [min, max):
x = Math.random() * (max - min) + min;
นั่นเป็นฟังก์ชั่นแรกจาก MDN ตัวที่สองคืนค่าจำนวนเต็มระหว่างmin
และmax
รวมทั้งสองอย่าง
ตอนนี้สำหรับการรับจำนวนเต็มคุณสามารถใช้round
, หรือceil
floor
คุณสามารถใช้Math.round(Math.random() * (max - min)) + min
สิ่งนี้ได้ แต่ให้การแจกแจงแบบไม่สม่ำเสมอ ทั้งสองmin
และmax
มีโอกาสเพียงประมาณครึ่งที่จะหมุน:
min...min+0.5...min+1...min+1.5 ... max-0.5....max
└───┬───┘└────────┬───────┘└───── ... ─────┘└───┬──┘ ← Math.round()
min min+1 max
ด้วยการยกเว้นจากช่วงเวลาก็มีโอกาสแม้แต่น้อยที่จะม้วนกว่าmax
min
กับMath.floor(Math.random() * (max - min +1)) + min
คุณมีการกระจายอย่างสมบูรณ์แบบแม้กระทั่ง
min.... min+1... min+2 ... max-1... max.... max+1 (is excluded from interval)
| | | | | |
└───┬───┘└───┬───┘└─── ... ┘└───┬───┘└───┬───┘ ← Math.floor()
min min+1 max-1 max
คุณไม่สามารถใช้ceil()
และ-1
ในสมการนั้นได้เนื่องจากmax
ตอนนี้มีโอกาสน้อยลงเล็กน้อยในการหมุน แต่คุณสามารถหมุนmin-1
ผลลัพธ์ที่ไม่ต้องการได้เช่นกัน
floor
ซึ่งรอบลง
round
แต่ทั้งคู่min
และmax
มีโอกาสเพียงครึ่งเดียวที่จะหมุนได้เหมือนกับหมายเลขอื่น ๆ ceil
คุณยังสามารถลบคุณหนึ่งและใช้เวลา อย่างไรก็ตามการทำเช่นนี้จะทำให้max
หมายเลขมีโอกาสน้อยลงในการหมุนเนื่องจาก[0,1)
ช่วงเวลาน้อยที่สุด
var randomnumber = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
(Math.random() * (maximum - minimum + 1) ) << 0
นั้นเร็วกว่า
x << 0
, x | 0
, ~~x
) แทนการMath.floor()
แปรรูปx
เป็นสองส่วนเติมเต็มกับช่วงที่มีขนาดเล็กกว่าNumber.MAX_SAFE_INTEGER
(เทียบกับ2³²⁻¹2⁵³) จึงทำให้คุณต้องใช้ด้วยความระมัดระวัง!
657348096152|0
ได้ 218099864 (110011111111111111000010011000 เป็นเลขฐานสอง)
ส่งคืนตัวเลขสุ่มจำนวนเต็มระหว่างนาที ( รวม ) และสูงสุด ( รวมอยู่ด้วย ):
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
หรือตัวเลขสุ่มใด ๆระหว่างขั้นต่ำ ( รวม ) และสูงสุด ( ไม่รวม ):
function randomNumber(min, max) {
return Math.random() * (max - min) + min;
}
ตัวอย่างที่เป็นประโยชน์ (จำนวนเต็ม):
// 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;
** และน่าจดจำเสมอ (Mozilla):
Math.random () ไม่ได้ให้ตัวเลขสุ่มที่ปลอดภัยเข้ารหัส อย่าใช้สิ่งใดก็ตามที่เกี่ยวข้องกับความปลอดภัย ใช้ Web Crypto API แทนและแม่นยำมากขึ้นกับวิธี window.crypto.getRandomValues ()
function getRandomizer(bottom, top) {
return function() {
return Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom;
}
}
การใช้งาน:
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.
}
ทำให้พังถล่ม:
เราจะส่งคืนฟังก์ชัน (ยืมจากการเขียนโปรแกรมฟังก์ชั่น) ที่เมื่อเรียกว่าจะส่งคืนจำนวนเต็มแบบสุ่มระหว่างค่าbottom
และtop
รวม เราพูดว่า "รวม" เพราะเราต้องการรวมทั้งด้านล่างและด้านบนในช่วงของตัวเลขที่สามารถส่งคืนได้ วิธีนี้getRandomizer( 1, 6 )
จะส่งคืน 1, 2, 3, 4, 5 หรือ 6
(ด้านล่างคือจำนวนที่ต่ำกว่าด้านบนเป็นจำนวนที่มากกว่า)
Math.random() * ( 1 + top - bottom )
Math.random()
ผลตอบแทนที่ได้สุ่มคู่ระหว่าง 0 และ 1, และถ้าเราคูณด้วยหนึ่งบวกความแตกต่างระหว่างtop
และbottom
เราจะได้รับบางคู่ระหว่างและ0
1+b-a
Math.floor( Math.random() * ( 1 + top - bottom ) )
Math.floor
ปัดเศษตัวเลขลงให้เป็นจำนวนเต็มที่ใกล้ที่สุด ดังนั้นตอนนี้เรามีจำนวนเต็มทั้งหมดระหว่างและ0
top-bottom
คนที่ 1 ดูสับสน แต่มันต้องอยู่ที่นั่นเพราะเราปัดเศษลงเสมอดังนั้นหมายเลขสูงสุดจึงไม่สามารถเข้าถึงได้โดยที่ไม่มี ทศนิยมสุ่มเราสร้างความต้องการที่จะอยู่ในช่วง0
การ(1+top-bottom)
เพื่อให้เราสามารถปัดเศษลงและได้รับการ int ในช่วง0
ที่จะtop-bottom
Math.floor( Math.random() * ( 1 + top - bottom ) ) + bottom
รหัสในตัวอย่างก่อนหน้านี้ทำให้เรามีจำนวนเต็มในช่วง0
และtop-bottom
ดังนั้นสิ่งที่เราต้องทำตอนนี้คือการเพิ่มbottom
ไปที่ผลลัพธ์เพื่อรับจำนวนเต็มในช่วงbottom
และtop
รวม : D
หมายเหตุ: หากคุณส่งผ่านค่าที่ไม่เป็นจำนวนเต็มหรือจำนวนที่มากกว่าก่อนคุณจะได้รับพฤติกรรมที่ไม่พึงประสงค์ แต่ถ้าใครร้องขอมันฉันจะไม่เจาะเข้าไปในรหัสตรวจสอบการโต้แย้งว่ามันค่อนข้างไกลจากเจตนาของคำถามเดิม .
function randomRange(min, max) {
return ~~(Math.random() * (max - min + 1)) + min
}
ทางเลือกถ้าคุณใช้Underscore.jsคุณสามารถใช้ได้
_.random(min, max)
_.uniqueId()
ฟังก์ชันที่คุณสามารถเรียกใช้โมเดลฝั่งไคลเอ็นต์
x << 0
, x | 0
, ~~x
) แทนการMath.floor()
แปรรูปx
เป็นสองส่วนเติมเต็มกับช่วงที่มีขนาดเล็กกว่าNumber.MAX_SAFE_INTEGER
(เทียบกับ2³²⁻¹2⁵³) จึงทำให้คุณต้องใช้ด้วยความระมัดระวัง!
ส่งคืนตัวเลขสุ่มระหว่าง 1 ถึง 10:
Math.floor((Math.random()*10) + 1);
ส่งคืนตัวเลขสุ่มระหว่าง 1 ถึง 100:
Math.floor((Math.random()*100) + 1)
คำตอบอื่น ๆ ไม่บัญชีสำหรับพารามิเตอร์ที่เหมาะสมอย่างสมบูรณ์แบบของและ0
1
แต่คุณควรใช้round
แทนของceil
หรือ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
console.log(randomNumber(5,6)); # 9 6 6 5 7 7
9 และ 7 มาระหว่าง 5 และ 6 หรือไม่? ...... คุณควรแก้ไขหรืออธิบาย ..
นี่คือการใช้ MS DotNet ในชั้นเรียนแบบสุ่มใน 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;
}());
ใช้:
var r = new Random();
var nextInt = r.Next(1, 100); //returns an integer between range
var nextDbl = r.NextDouble(); //returns a random decimal
ใช้ฟังก์ชันนี้เพื่อรับตัวเลขสุ่มระหว่างช่วงที่กำหนด
function rnd(min,max){
return Math.floor(Math.random()*(max-min+1)+min );
}
หลังจากสร้างหมายเลขสุ่มโดยใช้โปรแกรมคอมพิวเตอร์ก็ยังถือว่าเป็นหมายเลขสุ่มถ้าหมายเลขที่เลือกเป็นส่วนหนึ่งหรือเต็มหนึ่งของเริ่มต้น แต่หากมีการเปลี่ยนแปลงนักคณิตศาสตร์จะไม่ยอมรับว่าเป็นหมายเลขสุ่มและพวกเขาสามารถเรียกมันว่าเป็นหมายเลขที่มีอคติ แต่ถ้าคุณกำลังพัฒนาโปรแกรมสำหรับงานง่ายๆสิ่งนี้จะไม่เป็นสิ่งที่ควรพิจารณา แต่ถ้าคุณกำลังพัฒนาโปรแกรมเพื่อสร้างตัวเลขสุ่มสำหรับสิ่งที่มีค่าเช่นโปรแกรมลอตเตอรีหรือเกมการพนันโปรแกรมของคุณจะถูกปฏิเสธโดยผู้บริหารหากคุณไม่ได้พิจารณาเกี่ยวกับกรณีข้างต้น
ดังนั้นสำหรับคนประเภทนี้นี่คือคำแนะนำของฉัน:
สร้างหมายเลขสุ่มโดยใช้Math.random()
(พูดแบบนี้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.
หากคุณรู้วิธีอ่านตารางตัวเลขสุ่มเพื่อเลือกหมายเลขสุ่มคุณรู้ว่ากระบวนการข้างต้น (คูณด้วย 1, 10, 100 และต่อ ๆ ไป) จะไม่เป็นการละเมิดที่ฉันถูกกล่าวถึงในตอนเริ่มต้น (เพราะเปลี่ยนเฉพาะ ตำแหน่งของจุดทศนิยม)
ศึกษาตัวอย่างต่อไปนี้และพัฒนาตามความต้องการของคุณ
หากคุณต้องการตัวอย่าง [0,9] ดังนั้นชั้นของ n * 10 คือคำตอบของคุณและถ้าต้องการ [0,99] ดังนั้นชั้นของ n * 100 คือคำตอบของคุณเป็นต้น
ตอนนี้ให้เข้าสู่บทบาทของคุณ:
คุณถามตัวเลขในช่วงที่กำหนด (ในกรณีนี้คุณมีอคติในช่วงนั้น - จากการเอาตัวเลขจาก [1,6] โดยการหมุนตายแล้วคุณจะเอนเอียงไปที่ [1,6] แต่ก็ยังเป็นการสุ่มถ้าหากความตายไม่เอนเอียง .)
ดังนั้นให้พิจารณาช่วงของคุณ ==> [78, 247] จำนวนองค์ประกอบของช่วง = 247 - 78 + 1 = 170; (เนื่องจากขอบเขตทั้งสองรวมอยู่ด้วย
/*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);
หมายเหตุ: ในวิธีที่หนึ่งก่อนอื่นฉันจะสร้างอาร์เรย์ซึ่งมีตัวเลขที่คุณต้องการจากนั้นจึงสุ่มไปยังอาร์เรย์อื่น ในวิธีที่สองสร้างตัวเลขแบบสุ่มและตรวจสอบว่าอยู่ในช่วงที่คุณต้องการ จากนั้นใส่มันลงในอาร์เรย์ ที่นี่ฉันสร้างตัวเลขสุ่มสองตัวและใช้ผลรวมของพวกเขาเพื่อเพิ่มความเร็วของโปรแกรมโดยลดอัตราความล้มเหลวที่จะได้รับหมายเลขที่มีประโยชน์ อย่างไรก็ตามการเพิ่มจำนวนที่สร้างขึ้นก็จะทำให้บางสิ่งบางอย่าง biassness ดังนั้นฉันขอแนะนำวิธีแรกของฉันในการสร้างตัวเลขสุ่มภายในช่วงที่กำหนด
ในทั้งสองวิธีคอนโซลของคุณจะแสดงผลลัพธ์ (กด f12 ใน Chrome เพื่อเปิดคอนโซล)
Math.floor(Math.random() * (6 - 1 + 1) + 1)
] หมายเลข 1 และ 6 จะต้องถูกหมุนน้อยกว่า 2, 3, 4 และ 5 อย่างไรก็ตามความแตกต่างนั้นไม่มีนัยสำคัญ
สำหรับจำนวนเต็มแบบสุ่มที่มีช่วงลอง:
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;
}
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)));
}
ในการทดสอบฟังก์ชั่นนี้และรูปแบบของฟังก์ชั่นนี้ให้บันทึก HTML / JavaScript ด้านล่างลงในไฟล์และเปิดด้วยเบราว์เซอร์ รหัสจะสร้างกราฟที่แสดงการกระจายของการเรียกฟังก์ชันหนึ่งล้าน รหัสจะบันทึกกรณีขอบดังนั้นหากฟังก์ชันสร้างค่ามากกว่าค่าสูงสุดหรือน้อยกว่าค่าขั้นต่ำคุณจะต้อง. you.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"> [' + (i + min - 1) + ']: '+array[i]+'</span> ');
}
document.write('<hr/>');
</script>
</head>
<body>
</body>
</html>
ในการรับตัวเลขสุ่มพูดระหว่าง 1 ถึง 6 ให้ทำก่อน:
0.5 + (Math.random() * ((6 - 1) + 1))
นี่จะคูณจำนวนสุ่มด้วย 6 แล้วบวก 0.5 เข้าไป ปัดเศษตัวเลขเป็นจำนวนเต็มบวกโดยทำ:
Math.round(0.5 + (Math.random() * ((6 - 1) + 1))
ปัดเศษตัวเลขเป็นจำนวนเต็มที่ใกล้เคียงที่สุด
หรือเพื่อให้เข้าใจได้มากขึ้นให้ทำสิ่งนี้:
var value = 0.5 + (Math.random() * ((6 - 1) + 1))
var roll = Math.round(value);
return roll;
โดยทั่วไปรหัสสำหรับการทำเช่นนี้โดยใช้ตัวแปรคือ:
var value = (Min - 0.5) + (Math.random() * ((Max - Min) + 1))
var roll = Math.round(value);
return roll;
เหตุผลที่นำค่า 0.5 จากค่าต่ำสุดมาใช้เพราะการใช้ค่าขั้นต่ำเพียงอย่างเดียวจะช่วยให้คุณได้รับจำนวนเต็มที่มากกว่าหนึ่งค่าสูงสุดของคุณ ด้วยการละ 0.5 จากค่าต่ำสุดคุณจะป้องกันไม่ให้ค่าสูงสุดถูกปัดเศษ
หวังว่าจะช่วย
การใช้รหัสต่อไปนี้คุณสามารถสร้างอาร์เรย์ของตัวเลขสุ่มโดยไม่ต้องทำซ้ำในช่วงที่กำหนด
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;
}
ฉันรู้ว่าคำถามนี้ได้รับคำตอบแล้ว แต่คำตอบของฉันสามารถช่วยใครบางคน
ฉันพบวิธีการง่าย ๆ ใน W3Schools:
Math.floor((Math.random() * max) + min);
หวังว่านี่จะช่วยใครซักคน
สุ่มจำนวนเต็มระหว่างต่ำสุดและสูงสุด:
function randomRange(l,h){
var range = (h-l);
var random = Math.floor(Math.random()*range);
if (random === 0){random+=1;}
return l+random;
}
ไม่ใช่ทางออกที่หรูหราที่สุด .. แต่มีบางอย่างที่รวดเร็ว
นี่คือสิ่งที่ฉันใช้ในการสร้างตัวเลขสุ่ม
function random(high,low) {
high++;
return Math.floor((Math.random())*(high-low))+low;
}
เราดำเนินการhigh++
เพราะMath.random()
สร้างตัวเลขสุ่มระหว่าง 0, (รวม) และ 1 (ไม่รวม) คนที่ถูกยกเว้นหมายความว่าเราจะต้องเพิ่มความสูงโดยหนึ่งก่อนที่จะดำเนินการทางคณิตศาสตร์ใด ๆ จากนั้นเราก็ลบค่าต่ำจากระดับสูงให้จำนวนสูงสุดในการสร้าง - ต่ำจากนั้น + ต่ำนำค่าสูงกลับมาเป็นปกติและทำให้ตัวเลขต่ำสุดต่ำที่สุด จากนั้นเราส่งคืนหมายเลขผลลัพธ์
random(7,3)
สามารถกลับมา 3,4,5,6, or 7
high
เดียวกับที่ใช้เพียงครั้งเดียวคุณอาจใช้high-low+1
แทนที่จะมีคำสั่งเพิ่มแยกต่างหาก นอกจากนี้ผู้ใช้ส่วนใหญ่คาดหวังว่าlow
พารามิเตอร์จะมาก่อน
<!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 สร้างอาร์เรย์ที่เต็มไปด้วยตัวเลขสูงสุด 3 หลักซึ่งจะเป็นสูงสุด 999 รหัสนี้สั้นมาก
นี่คือตัวอย่างของฟังก์ชั่นจาวาสคริปต์ที่สามารถสร้างจำนวนสุ่มของความยาวที่ระบุใด ๆโดยไม่ต้องใช้ 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;
}
นี่คือการสุ่มตัวเลขในช่วงเนื่องจากฉันต้องการรับตัวเลขสุ่มภายในช่วงของเลขฐานเป็นเลขชี้กำลัง เช่น base = 10, exponent = 2, ให้ตัวเลขสุ่มตั้งแต่ 0 ถึง 100, เป็นการดีเลิศและอื่น ๆ
ถ้ามันช่วยใช้มันนี่คือ:
// 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);
Math.random()
รวดเร็วและเหมาะสำหรับวัตถุประสงค์หลายอย่าง แต่มันไม่เหมาะสมถ้าคุณต้องการค่าที่ปลอดภัยแบบเข้ารหัส (ไม่ปลอดภัย) หรือถ้าคุณต้องการจำนวนเต็มจากการกระจายแบบไม่เอนเอียงที่สมบูรณ์แบบเหมือนกัน (วิธีการคูณที่ใช้ในคำตอบอื่น ๆ กว่าคนอื่น ๆ )
ในกรณีเช่นนี้เราสามารถใช้crypto.getRandomValues()
เพื่อสร้างจำนวนเต็มที่ปลอดภัยและปฏิเสธค่าใด ๆ ที่สร้างขึ้นซึ่งเราไม่สามารถแมปอย่างสม่ำเสมอในช่วงเป้าหมาย สิ่งนี้จะช้าลง แต่ไม่ควรมีนัยสำคัญหากคุณไม่ได้สร้างคุณค่าจำนวนมาก
ในการชี้แจงข้อกังวลเกี่ยวกับการแจกแจงแบบเอนเอียงให้พิจารณากรณีที่เราต้องการสร้างค่าระหว่าง 1 ถึง 5 แต่เรามีตัวสร้างตัวเลขสุ่มที่สร้างค่าระหว่าง 1 ถึง 16 (ค่า 4 บิต) เราต้องการให้มีการแมปค่าที่สร้างขึ้นจำนวนเท่ากันกับแต่ละค่าเอาต์พุต แต่ 16 ไม่ได้แบ่งเท่า ๆ กัน 5: มันเหลือเศษ 1 ดังนั้นเราจำเป็นต้องปฏิเสธ 1 ค่าที่สร้างขึ้นได้และต่อเมื่อเราได้รับเท่านั้น หนึ่งใน 15 ค่าที่น้อยกว่าซึ่งสามารถแมปอย่างสม่ำเสมอในช่วงเป้าหมายของเรา พฤติกรรมของเราอาจมีลักษณะเหมือนรหัสเทียมนี้:
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.
รหัสต่อไปนี้ใช้ตรรกะที่คล้ายกัน แต่สร้างจำนวนเต็ม 32 บิตแทนเพราะนั่นเป็นขนาดจำนวนเต็มทั่วไปที่ใหญ่ที่สุดที่สามารถแสดงด้วยnumber
ชนิดมาตรฐานของ JavaScript (สิ่งนี้สามารถแก้ไขเพื่อใช้BigInt
s หากคุณต้องการช่วงที่ใหญ่กว่า) โดยไม่คำนึงถึงช่วงที่เลือกเศษส่วนของค่าที่สร้างขึ้นที่ถูกปฏิเสธจะน้อยกว่า 0.5 เสมอดังนั้นจำนวนการปฏิเสธที่คาดหวังจะน้อยกว่า 1.0 และ มักจะใกล้กับ 0.0; คุณไม่จำเป็นต้องกังวลเกี่ยวกับมันวนซ้ำตลอดไป
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]
หากต้องการรับจำนวนเต็มแบบสุ่มที่เข้ารหัสลับได้ใน ragne [x, y] ให้ลอง
let cs= (x,y)=>x+(y-x+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0
console.log(cs(4,8))
คุณสามารถโค้ดขนาดสั้นนี้ได้ไหม
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;
}
do - while
แทนwhile
Ionuț G. Stanเขียนคำตอบที่ยอดเยี่ยม แต่มันซับซ้อนเกินไปสำหรับฉันที่จะเข้าใจ ดังนั้นฉันจึงพบคำอธิบายที่ง่ายขึ้นของแนวคิดเดียวกันที่https://teamtreehouse.com/community/mathfloor-mathrandom-max-min-1min-explanationโดย Jason Anello
หมายเหตุ:สิ่งสำคัญเดียวที่คุณควรรู้ก่อนอ่านคำอธิบายของ Jason คือคำจำกัดความของ "ตัด" Math.floor()
เขาใช้คำว่าเมื่ออธิบาย พจนานุกรม Oxford กำหนด "truncate" เป็น:
ร่น (บางสิ่ง) โดยการตัดส่วนบนหรือส่วนท้าย
สิ่งนี้สามารถจัดการกับการสร้างตัวเลขสุ่มได้ไม่เกิน 20 หลัก
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);
/ * เขียนฟังก์ชั่นที่เรียกrandUpTo
ว่ารับหมายเลขและส่งกลับจำนวนเต็มแบบสุ่มระหว่าง 0 ถึงหมายเลขนั้น? * /
var randUpTo = function(num) {
return Math.floor(Math.random() * (num - 1) + 0);
};
/ * เขียนฟังก์ชั่นที่เรียกrandBetween
ว่ายอมรับตัวเลขสองตัวที่แทนช่วงและส่งกลับจำนวนเต็มแบบสุ่มระหว่างตัวเลขทั้งสอง * /
var randBetween = function (min, max) {
return Math.floor(Math.random() * (max - min - 1)) + min;
};
/ * เขียนฟังก์ชั่นที่เรียกrandFromTill
ว่ายอมรับตัวเลขสองตัวที่แทนช่วงและส่งกลับตัวเลขสุ่มระหว่าง min (รวม) และ max (พิเศษ) * /
var randFromTill = function (min, max) {
return Math.random() * (max - min) + min;
};
/ * เขียนฟังก์ชั่นที่เรียกrandFromTo
ว่ารับตัวเลขสองตัวที่เป็นตัวแทนของช่วงและส่งกลับจำนวนเต็มแบบสุ่มระหว่าง min (รวม) และ max (รวม) * /
var randFromTo = function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
ฉันสร้างฟังก์ชันนี้ซึ่งคำนึงถึงตัวเลือกบัญชีเช่น min, max, แยก (รายการของ ints ที่จะแยก) และ seed (ในกรณีที่คุณต้องการตัวสร้างแบบสุ่ม seeded)
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
}
มันสามารถใช้เช่น:
let n = get_random_int
(
{
min: 0,
max: some_list.length - 1,
exclude: [3, 6, 5],
seed: my_seed_function
}
)
หรือมากกว่านั้น:
let n = get_random_int
(
{
min: 0,
max: some_list.length - 1
}
)
จากนั้นคุณสามารถทำได้:
let item = some_list[n]
สรุปสาระสำคัญ: https://gist.github.com/madprops/757deb000bdec25776d5036dae58ee6e
Math.floor ปัดเศษตัวเลขลงให้เป็นจำนวนเต็มที่ใกล้เคียงที่สุด
function generateRandomInteger (min, max) {
return Math.floor(random(min,max))
}`
ดังนั้นหากต้องการสร้างจำนวนเต็มแบบสุ่มระหว่าง 4 ถึง 8 ให้เรียกฟังก์ชันข้างต้นด้วยอาร์กิวเมนต์ดังนี้
generateRandomInteger (4,9)
วิธีสร้างหมายเลขสุ่มระหว่าง 0 ถึง n ของฉันโดยที่ n <= 10 (ไม่รวม n):
Math.floor((Math.random() * 10) % n)