본문 바로가기

TIL

[TIL-107] 위코드 6일차: JS replit 22

Javascript

 

Math 객체

개념

Math 안에 다양한 수학 계산 메서드가 담겨있다. 예를 들어 Math.random()은 0 이상 1 미만의 소수를 랜덤으로 만들어준다. (이때까지 1도 포함되는 줄 알았는데 0.999999999까지만 나온다고 한다.) 보통 이 값을 그대로 사용하기보단, 원하는 범위가 있을 때 그 최대값을 이 값에 곱하고 다시 Math 객체 안의 메서드를 이용해서 정수로 만든다.

참고) JavaScript Math Object https://www.w3schools.com/js/js_math.asp

 

사용법

예) 최소값(min), 최대값(max)을 받아 그 사이의 랜덤수를 return 하는 함수

function getRandomNumber (min, max) {
  const randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
  return randomNum;
}
  • 0에서부터 자연수 N까지의 랜덤 수를 구하려면 Math.random()에 N+1을 곱한 값에 Math.floor()로 내림하면 된다.
    • N을 그대로 Math.random()에 곱하면, 올림인 Math.ceil()을 사용했을 때 0이 거의 나올 수 없다. Math.random() 값이 0일 때만 가능하기 때문이다.
    • 내림인 Math.floor()를 사용했을 때는 최대값인 N이 절대 나올 수 없다. Math.random()의 값에 1은 포함되지 않기 때문이다. 예를 들어, N이 3이라면 Math.random() * 3을 해도 2.999999까지밖에 나올 수 없기 때문에 여기서 내려버리면 최대 2까지밖에 나올 수 없다.
    • 그렇다고 Math.round()를 사용하는 건 최소값과 최대값이 나올 가능성이 그 사이 다른 수가 나올 가능성보다 작기 때문에 완전한 랜덤이라고 볼 수 없다. 예를 들어, 3을 곱해 0.00000에서 2.99999가 나온다면 이 값에 반올림해서 0이 나올 경우는 0.00000~0.49999까지지만 1이 나올 경우는 0.50000~1.49999까지로, 가능성이 2배나 된다. 최대값인 3이 나올 경우도 2.50000~2.99999까지이므로 범위의 가운데 숫자들보다 나올 가능성이 낮다.
    • 따라서 내림을 사용하는 대신, N에 1을 더한 값을 곱한다. 그럼 예를 들어, N이 3일 때 Math.random() * 4를 해서 0.0000에서 3.999999 사이의 값을 받아 소수점 아래를 버리고 0에서 3까지 숫자를 얻을 수 있다.
  • 하지만 범위에 음수도 포함된다면 단순히 최대값을 곱해서는 범위에 맞는 랜덤수를 구할 수 없다. 예를 들어, 범위가 -50에서 0까지라면 오히려 최솟값인 -50을 Math.random()에 곱하는 것이 적절하다.
  • 또한 최소값이 0이거나 최대값이 0인 경우가 아니라면 최대값이나 최소값을 곱하는 것만으로 범위에 맞는 랜덤수를 구할 수 없다. 예를 들어, 범위가 -10에서 15까지라면 -10을 곱해도, 15를 곱해도 엉망이다.
  • 따라서 최대값과 최소값의 차이를 범위로 랜덤수를 구해, 최소값에 더하는 것이 적절하다. (이 생각을 하기 전에는 앞서 말한 최대값과 최소값이 음수냐 양수냐의 경우에 따라 나눠서 구해야되나 했는데 그러면 머리 터지고 계산도 못하겠다.) 예를 들어, 범위가 -2에서 8일 때 0에서 (최대값과 최소값의 차이인) 10 사이의 랜덤수를 최소값인 -2에 더하면 된다.