다음 Javascript 코드는 1부터 100까지 랜덤한 정수를 구하는 계산이다.
// 1. Math.random() * 100은 0 이상 100 미만의 소수를 생성합니다.
// 2. Math.floor(Math.random() * 100)은 이 값을 내림 처리하여 0부터 99까지의 정수를 생성합니다.
// 3. 마지막으로 + 1을 더해 1부터 100까지의 정수를 생성합니다.
let randomInt = Math.floor(Math.random() * 100) + 1;
(0~100 의 난수를 내림처리 후 +1) 이런 방식으로 처리를 하는걸까?
(0~100의 난수를 올림처리) 를 하면 코드가 더 간결하지 않을까?
= Math.floor(Math.random() * 100) + 1; 대신에 Math.ceil(Math.random() * 100) 를 사용해도 되지 않을까?
..라는 궁금증이 생겼고, 이에 대해 이해한 내용을 기록하고자 본 게시글을 작성했습니다.
결론부터 말하자면, Math.floor(Math.random() * 100) + 1을 사용해야 한다.
Math.ceil(Math.random() * 100) 를 사용하면 1이 상대적으로 적게 나오기 때문에 불공평하다!
✅ 1. 질문의 시작
Math.ceil(Math.random() * 100)을 실행하면 1부터 100까지 랜덤한 정수가 나와야 합니다.
하지만 실제로는 1이 상대적으로 적게 나오는 현상이 발견됩니다.
✅ 2. 헷갈리는 이유는 이론적인 기대값 때문
- 0.000 ~ 0.999 → 1
- 1.000 ~ 1.999 → 2
- ...
- 99.000 ~ 99.999 → 100
모든 구간 길이는 1.0으로 이론적으로 균등하므로
각 숫자가 같은 확률로 나와야 할 것처럼 보입니다.
❗ 3. 그런데 실제로는 왜 1이 덜 나올까?
📌 원인 1: 부동소수점 정밀도 문제
- 실수는 무한히 많지만, 컴퓨터는 64비트(고정된 크기)로 표현합니다.
- 특히
0~1구간은 이진수로 정밀하게 표현하기 어려움. - → 표현 가능한 숫자가 상대적으로 적고 희박합니다.
📌 원인 2: 그 결과, 표현 가능한 값의 밀도 차이
0.00001 ~ 0.99999사이에는 표현 가능한 값이 드뭅니다.1.00001 ~ 1.99999구간은 상대적으로 더 조밀하게 표현 가능.- → 따라서
0~1에서 1이 나올 확률이 상대적으로 줄어듭니다.
✅ 4. 시뮬레이션을 통해 확인하기
1천만 개의 Math.random() * 100 실수 샘플을 생성해보면,
각 구간의 길이는 같지만 실제로 표현된 숫자의 밀도 차이로 인해 1의 빈도가 낮게 나옵니다.

✅ 5. 올바른 해결책
Math.floor(Math.random() * 100) + 1;
- 0~99를 만들고, +1 해서 1~100을 생성
- 정수 구간에 대해 균등한 확률 분포가 보장됩니다.
🎯 최종 요약
- 문제 원인: 부동소수점 정밀도 + 표현 가능한 실수 수의 밀도 차이로 인해 0~1 구간은 표현 가능한 실수가 희박함
- 결과: 1이 나올 확률이 상대적으로 줄어듦
- 추천 : 그러니 1부터 100까지의 정수를 생성하고 싶다면 Math.floor(...)+1 방식을 사용해야 한다
💡 덤: 부동소수점이란?
실수는 무한히 많지만, 컴퓨터는 메모리가 한정되어 있어서 유한한 비트 수로만 실수를 표현합니다.이를 위해 사용하는 방식이 부동소수점(Floating-point) 표현입니다.
예: 0.1 → 2진수로는 0.0001100110011...
'참고용' 카테고리의 다른 글
| RustDesk 중계 서버 구축하기 (3) | 2025.07.12 |
|---|---|
| 파이썬에서 딕셔너리(dict) ↔ JSON 변환하는 코드 (0) | 2025.05.20 |
| 리눅스 시스템 시간과 실제 시간이 맞지 않는 경우 (0) | 2025.04.22 |
| Chocolatey 설치 (0) | 2025.04.07 |
| Windows 환경에서 PuTTY를 이용해 ssh 접속하기 (0) | 2025.04.03 |