JavaScript에서 지정된 범위 (예 : 1에서 6 : 1, 2, 3, 4, 5 또는 6)의 난수를 생성하는 방법이 있습니까?
Math.floor((Math.random()*10)+1);
명시된대로 이와 같은 솔루션이 효과 가없는 이유는 무엇입니까?
JavaScript에서 지정된 범위 (예 : 1에서 6 : 1, 2, 3, 4, 5 또는 6)의 난수를 생성하는 방법이 있습니까?
Math.floor((Math.random()*10)+1);
명시된대로 이와 같은 솔루션이 효과 가없는 이유는 무엇입니까?
답변:
다음 코드는 최소값이 인 경우에만 작동합니다 1
. 이외의 최소값에는 작동하지 않습니다 1
.
1 과 1 사이의 임의의 정수를 얻으려면 다음 과 같이 계산하십시오.
Math.floor(Math.random() * 6) + 1
어디:
Math.floor(Math.random() * 6) + 2
하는 경우 있음을 의미 Math.random()
0.99 우리의 임의의 값으로 결과가 될 것이다7
function randomIntFromInterval(min, max) { // min and max included
return Math.floor(Math.random() * (max - min + 1) + min);
}
"추가"는 1로 시작하지 않는 임의의 간격을 허용한다는 것입니다. 예를 들어 10에서 15 사이의 임의의 숫자를 얻을 수 있습니다. 적응성.
to
arg를 포함하지 않으면 from
arg가 최대로 두 배가 되기 때문에 이것은 또한 좋습니다
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/… )
min ( 포함 )과 max ( 포함 ) 사이 의 정수 난수를 반환합니다 .
function randomInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
또는 min ( 포함 )과 max ( 포함되지 않음 ) 사이의 임의의 숫자 :
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 () 메소드입니다.
[1,2]
25 %의 확률이 Math.random()
이들 중 하나에서 당신에게 수를 줄 것이다가 [0,0.49]
, [0.5,0.99]
, [1,1.49]
, [1.5,1.99]
. 이러한 구간을 반올림하면 0, 1, 1, 2가되어 균일 한 분포가 아닙니다. 바닥재는 0, 0, 1, 1입니다.
Math.round
over를 사용 Math.floor
하면 다른 결과가 나오는 이유를 분명히하고 싶었습니다 .
function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
a | 0
또한 문자열을 정수로 변환하는 가장 빠르고 최적화 된 방법입니다. 정수 ( "444"
및 "-444"
)를 포함하는 문자열 , 즉 float / fraction 과만 작동합니다. 0
실패한 모든 것에 대해 a 를 산출 합니다. asm.js의 주요 최적화 중 하나입니다.
~~(Math.random() * (50000000000000 - 0 + 1)) + 0
하고Math.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
TL; DR
function generateRandomInteger(min, max) {
return Math.floor(min + Math.random()*(max + 1 - min))
}
난수를 얻으려면
generateRandomInteger(-20, 20);
아래 설명
최소와 최대 사이의 X 와 같은 임의의 정수를 가져와야합니다.
권리?
즉 최소 <= X <= 최대
방정식에서 min을 빼면 다음과 같습니다.
0 <= (X-최소) <= (최대-최소)
이제 임의의 숫자와 곱셈이 있습니다 R 입니다
0 <= (X-최소) * r <= (최대-최소) * r
이제 방정식에 최소값 을 다시 추가 합니다
최소 <= 최소 + (X-최소) * r <= 최소 + (최대-최소) * r
이제 우리의 방정식 범위가 [min, max]를 만족하도록 r이 되는 함수를 선택해 봅시다. 0 <= r <= 1 인 경우에만 가능합니다.
확인. 지금의 범위 (R)의 예 [0,1] 인 Math.random () 함수의 결과와 매우 유사하다. 그렇지 않습니까?
Math.random () 함수는 [0, 1) 범위의 부동 소수점 의사 난수를 반환합니다. 즉, 0 (포함)부터 1 (제외)까지는 포함하지 않음
예를 들어
min
+ 0 * ( max
- min
) = 분
min
+ 1 * ( max
- min
) = 최대
min
+ r * ( max
- min
) = X. 여기서 X의 범위는 최소 <= X < 최대입니다.
위의 결과 X 는 임의의 숫자입니다. 그러나 Math.random ()으로 인해 왼쪽 경계가 포함되고 오른쪽 경계가 배타적입니다. 오른쪽 경계를 포함하기 위해 오른쪽 경계를 1 씩 늘리고 결과를 바닥에 둡니다.
function generateRandomInteger(min, max) {
return Math.floor(min + Math.random()*(max + 1 - min))
}
generateRandomInteger(-20, 20)
;
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;
jsfiddle : https://jsfiddle.net/cyGwf/477/
Random Integer : min
와 사이에 임의의 정수를 얻으려면 max
다음 코드를 사용하십시오.
function getRandomInteger(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
임의의 부동 소수점 수 : min
와 사이에 임의의 부동 소수점 수를 얻으려면 max
다음 코드를 사용하십시오.
function getRandomFloat(min, max) {
return Math.random() * (max - min) + min;
}
참조 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
수학은 나의 장점이 아니지만 양수와 음수 사이에 많은 난수를 생성 해야하는 프로젝트를 진행하고 있습니다.
function randomBetween(min, max) {
if (min < 0) {
return min + Math.random() * (Math.abs(min)+max);
}else {
return min + Math.random() * max;
}
}
예 :
randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)
물론, 숫자 이외의 다른 작업으로이 작업을 수행하지 않도록 유효성 검사를 추가 할 수도 있습니다. 또한 min이 항상 max보다 작거나 같아야합니다.
min + Math.random() * max
min과 min + max 사이의 숫자를 제공하므로 원하는 것이 아닙니다. 의 첫 번째 분기 if
는 정확하지만 간단히 말할 수 있습니다 .min return min + Math.random() * (max - min)
이 양수인지 음수인지에 관계없이 올바른 솔루션입니다 (다른 답변 참조). 또한 분수를 원하지 않는 경우 결과를 계속 계산해야합니다.
나는 정수뿐만 아니라 임의의 숫자를 줄 수있는보다 유연한 함수를 작성했습니다.
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
고정 버전.
예
1에서 10 사이의 난수를 반환합니다.
Math.floor((Math.random() * 10) + 1);
결과는 다음과 같습니다.
3
너 자신을보십시오 : 여기
-
또는 lodash / undescore를 사용하십시오.
_.random(min, max)
많은 답변과 거의 동일한 결과에도 불구하고. 내 답변을 추가하고 작동 방법을 설명하고 싶습니다. 한 줄의 코드를 복사하여 붙여 넣기보다는 작업 내용을 이해하는 것이 중요합니다. 난수를 생성하는 것은 단순한 수학 일뿐입니다.
암호:
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));
}
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 비트 정수를 생성합니다. 이는 JavaScript의 표준 number
유형 으로 표시 될 수있는 가장 큰 공통 정수 크기이기 때문입니다 . (이것은 사용하도록 수정 될 수있는 BigInt
더 큰 범위를 필요로하는 경우들.)에 관계없이 선택된 범위, 항상, 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]
@Francisc 의 답변 float
버전을 기반으로 고정밀 버전으로 추가 int
:
function randomFloatFromInterval (min, max, fractionDigits) {
const fractionMultiplier = Math.pow(10, fractionDigits)
return Math.round(
(Math.random() * (max - min) + min) * fractionMultiplier,
) / fractionMultiplier
}
그래서:
randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...
int 답변
randomFloatFromInterval(1,3,0) // => 1, 2, 3
[a, b] 범위의 암호화 강력 난수 (가정 : a <b)
let rand= (a,b)=> a+(b-a+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0
console.log( rand(1,6) );
이것은 약 9 년 늦었지만 randojs.com은이 를 간단한 단일 라이너로 만듭니다.
rando(1, 6)
이것을 html 문서의 머리 부분에 추가하기 만하면 원하는대로 무엇이든 원하는대로 쉽게 할 수 있습니다. 배열의 임의의 값, 임의의 jquery 요소, 개체의 임의의 속성 및 필요한 경우 반복을 방지합니다.
<script src="https://randojs.com/1.0.0.js"></script>
이것은 저에게 효과적이며 Python의 random.randint 표준 라이브러리 함수 와 같은 값을 생성합니다 .
function randint(min, max) {
return Math.round((Math.random() * Math.abs(max - min)) + min);
}
console.log("Random integer: " + randint(-5, 5));