JavaScript에서 두 숫자 사이의 난수 생성


1796

JavaScript에서 지정된 범위 (예 : 1에서 6 : 1, 2, 3, 4, 5 또는 6)의 난수를 생성하는 방법이 있습니까?


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

65
물론 수학 바닥 (Math.random () * 6 + 1)
Amjad

3
Nabil Kadimi는 음수를 생성하는 방법에 대한 기사를 썼습니다 .
madc

유용한 요지가 여기 있습니다 : gist.github.com/kerimdzhanov/7529623
Dan KK

w3schools.com/jsref/jsref_random.asp에Math.floor((Math.random()*10)+1); 명시된대로 이와 같은 솔루션이 효과 가없는 이유는 무엇입니까?
shashwat

답변:


2115

중대한

다음 코드는 최소값이 인 경우에만 작동합니다 1. 이외의 최소값에는 작동하지 않습니다 1.

1 1 사이의 임의의 정수를 얻으려면 다음 과 같이 계산하십시오.

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

어디:

  • 1은 시작 번호입니다
  • 6은 가능한 결과 수입니다 (1 + 시작 (6) -끝 (1) )

45
@Mike와 같이 작동하지만 Francisc이 아래에있는 것처럼 더 일반적인 버전을 지적하는 것이 가장 좋습니다 :-).
Raymond Machira

58
-1. 인터넷 검색 후 제목이 ""자바 스크립트에서 두 숫자 사이의 임의의 값 생성 "입니다. 최소값이 0 인 경우 작동하지 않음
Ydhem

18
예를 들어 두 개의 큰 숫자 사이의 숫자를 원하면 작동하지 않습니다. Math.floor (Math.random () * 900) + 700
Rob

14
최소 2이며, 우리는 여전히 사용하는 경우 최소 1 인 경우 그에만 작동 Math.floor(Math.random() * 6) + 2하는 경우 있음을 의미 Math.random()0.99 우리의 임의의 값으로 결과가 될 것이다7
항독소의

27
이 코드는 어떤 숫자에서도 작동하지 않기 때문에 좋지 않습니다. @Francisc 코드가 맞습니다.
라이온 킹

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

"추가"는 1로 시작하지 않는 임의의 간격을 허용한다는 것입니다. 예를 들어 10에서 15 사이의 임의의 숫자를 얻을 수 있습니다. 적응성.


5
누군가가 toarg를 포함하지 않으면 fromarg가 최대로 두 배가 되기 때문에 이것은 또한 좋습니다
Jason

12
안녕하세요. 이것은 MDN에서 온 것입니다 : 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
위의 의견을 읽으십시오. 랜덤은 [0,1]이 아닌 [0,1) 안에 있습니다.
Francisc

3
낮은 숫자가 0 인 경우 큰 작품
로빈 짐머만

2
이 솔루션은 min과 max가 정수인 경우에만 정확합니다. 그렇지 않으면 [min, ceil (max)] 간격으로 결과를 얻을 수 있습니다. 즉, 최대보다 높기 때문에 범위를 벗어난 결과를 얻을 수 있습니다.
collimarco

326

Math.random ()

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 ​​() 메소드입니다.


나를 혼란스럽게 한 것은 ... Math.floor (..)는 숫자가 Math.round (..)가 고르지 않은 분포를 제공하는 정수임을 보장합니다. 참조 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
alikuli

1
나는이 대답을 믿습니다. 누구나 이것이 왜 작동하는지에 대한 링크 또는 명확한 설명을 줄 수 있습니까? 아마도 Math.round가 어떻게 편향을 줄 수 있는지에 대한 예일 것입니다. 그리고 왜 우리는이 복잡한 관찰 공식을 사용해야합니까?
Robin Andrews

6
@alikuli의 범위의 경우 [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입니다.
pishpish

1
@shuji이 있다 정답, 다른 사람의 사이에서. Math.roundover를 사용 Math.floor하면 다른 결과가 나오는 이유를 분명히하고 싶었습니다 .
pishpish

내가 찾은 가장 정확한 솔루션 : function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik

91

다른 솔루션 :

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

온라인으로 시도


6
~~ sintaxis를 설명 (또는 참조) 할 수 있습니까? 나는 전에 그것을 보지 못했다! 우아한 솔루션이지만 이해하기 어렵습니다.
DiegoDD

27
Double Tilde ~~aBitwise OR (a | 0)은 Math.floor (a)를 작성하는 가장 빠른 방법입니다.
edi9999

7
a | 0또한 문자열을 정수로 변환하는 가장 빠르고 최적화 된 방법입니다. 정수 ( "444""-444")를 포함하는 문자열 , 즉 float / fraction 과만 작동합니다. 0실패한 모든 것에 대해 a 를 산출 합니다. asm.js의 주요 최적화 중 하나입니다.
pilau

3
참고 : 실제로 큰 숫자로 작업하는 경우 이중 물결표가 작동하지 않습니다. 시도 ~~(Math.random() * (50000000000000 - 0 + 1)) + 0하고Math.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM

3
"더블 틸드와 비트 OR 또는 수학 도트 플로어를 작성하는 더 빠른 방법"은 내 아침을 밝게 한 아름다운 운이 좋은 커플입니다. 감사합니다 @ edi9999!
teedyay

60

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 (제외)까지는 포함하지 않음

예를 들어

사례 r = 0

min+ 0 * ( max- min) =

사례 r = 1

min+ 1 * ( max- min) = 최대

Math.random 0 <= r <1을 사용한 임의의 경우

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



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

2
과연. 나는 랜드가 0 인 것을 잊었다. 고쳤다.
ryebr3ad

3
그것은 의사 코드의 일부입니다 ... 누군가는 그것이 실제라고 생각하고 그것을 사용하려고 시도 할 수 있습니다.
gravityboy

35
@gravityboy 무슨 소리 야? 누군가 [숫자 선택 ...] 대신 숫자를 대체 할 수없는 경우 프로그래머로 적합하지 않을 수 있습니다.
ryebr3ad

7
@ ryebr3ad -1! 그것은 의사 코드가 아닌 자바 스크립트로 말해지고 모든 독자가 프로그래머가되는 것은 아닙니다. 많은 사람들이 초보자입니다!
Steve

3
@ ryebr3ad : 인턴에게 지원이 필요한 데이터베이스 환경에 대해 가르치는 동료가 있습니다. 그는 그들에게 테이블에서 모든 것을 선택하라고 지시했고 SQL 쿼리 편집기에서 바로 "select from out from ..."을 쓰기 시작했습니다. 그는 당신과 같은 반응을 보였습니다.
Ellesedil

22

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


14

수학은 나의 장점이 아니지만 양수와 음수 사이에 많은 난수를 생성 해야하는 프로젝트를 진행하고 있습니다.

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보다 작거나 같아야합니다.


5
이것은 단순히 잘못입니다. min + Math.random() * maxmin과 min + max 사이의 숫자를 제공하므로 원하는 것이 아닙니다. 의 첫 번째 분기 if는 정확하지만 간단히 말할 수 있습니다 .min return min + Math.random() * (max - min)이 양수인지 음수인지에 관계없이 올바른 솔루션입니다 (다른 답변 참조). 또한 분수를 원하지 않는 경우 결과를 계속 계산해야합니다.
Avish

10

나는 정수뿐만 아니라 임의의 숫자를 줄 수있는보다 유연한 함수를 작성했습니다.

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

고정 버전.


최소값으로 0으로 작동하지 않으므로 좋은 해결책이 아닙니다. @Lior의 답변을 참조하십시오.
Sebastien

물론 최소값으로 0으로 작동합니다. 시도해 보았 니? 작동하지 않는 이유는 없습니다. 이상하지 않은 간격으로 0으로 작동하지 않습니다 (간격 = 0? ...).
ElChupacabra

이 값을 최소값으로 0으로 여러 번 실행했지만 출력에서 ​​0을 얻지 못했습니다. 또는 나는 운이 좋지 않다 ...
Sebastien

네 말이 맞아 "+ 간격"이 잘못되었습니다. 지금 테스트하십시오. 때때로 console.log가 3 * 0.1과 같이 0.3 대신 0.300000004를 제공하는 이상한 것은 정확히 0.3이 아닙니다.
ElChupacabra

9

1에서 10 사이의 난수를 반환합니다.

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

결과는 다음과 같습니다. 3

너 자신을보십시오 : 여기

-

또는 lodash / undescore를 사용하십시오.

_.random(min, max)

문서 : -Lodash - Undescore


1
9 또는 10이 필요합니까? 그렇다면 const constNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber % 2 === 0? 9 : 10
Sebastián Lara

7

많은 답변과 거의 동일한 결과에도 불구하고. 내 답변을 추가하고 작동 방법을 설명하고 싶습니다. 한 줄의 코드를 복사하여 붙여 넣기보다는 작업 내용을 이해하는 것이 중요합니다. 난수를 생성하는 것은 단순한 수학 일뿐입니다.

암호:

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로 작성된 난수 생성기를 검색하고 있으며 모든 답변을 읽은 후 이것을 작성했습니다. TypeScript 코더에서 작동하기를 바랍니다.

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

5

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]


자, 이것이 내가 과잉이라고 부르는 것입니다.
2x 사무라이

2
@ 2xSamurai 거기서, 왜 이것이 필요할지, 어떻게 작동하는지 설명하기 위해 답변을 업데이트했습니다. 더 낫습니까? : P
Jeremy Banks

암호로 안전하고 균일하게 분포 된 난수를 원한다면 과도하지 않습니다. 이러한 요구 사항을 충족시키는 난수를 생성하는 것은 어렵습니다. 정답입니다, @JeremyBanks.
thomaskonrad

4

@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


1

이것은 작동해야합니다 :

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

1

ES6 기본 매개 변수를 사용하여이를 수행하는 새로운 방법을 발견했습니다. 하나의 인수 또는 두 개의 인수를 허용하기 때문에 매우 깔끔합니다. 여기있어:

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

1

이것은 약 9 년 늦었지만 randojs.com은이 를 간단한 단일 라이너로 만듭니다.

rando(1, 6)

이것을 html 문서의 머리 부분에 추가하기 만하면 원하는대로 무엇이든 원하는대로 쉽게 할 수 있습니다. 배열의 임의의 값, 임의의 jquery 요소, 개체의 임의의 속성 및 필요한 경우 반복을 방지합니다.

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

이미 한 줄짜리 작업을 수행하기 위해 종속성을 추가하는 이유는 무엇입니까? JS 커뮤니티에 라이브러리를 추가하는 것에 대한 집착은 미친 짓입니다
Daniel Cooke

읽고 기억하기 쉽습니다. 동의합니다
Aaron Plocharczyk

1

이것은 저에게 효과적이며 Python의 random.randint 표준 라이브러리 함수 와 같은 값을 생성합니다 .


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

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

1

다음을 사용하십시오.

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


1

기본적으로 주사위처럼 1-6을 반환합니다.

return Math.round(Math.random() * 5 + 1);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.