자바에서는 수학 연산에 필요한 기능들을
java.lang.Math 클래스에 정적 메서드 형태로 제공한다.
Math 클래스는 연산을 다루는 유틸리티 클래스이며
별도의 객체 생성 없이 바로 사용할 수 있다.
이러한 설계 방식은 정적 메서드와 관련된 개념으로
해당 내용은 다음(link) 내용에 정리되어 있다. (곧 추가 할 예정)
이 글에서는 Math 클래스가 제공하는 여러 기능 중
난수 생성을 담당하는 Math.random() 메서드를 중심으로
동작 방식과 사용 시 주의점을 정리한다.
Math.random( )은 난수(random number)를 생성하기 위한 메서드다.
double value = Math.random();
이 메서드는 호출할 때마다 다음과 같은
임의의 실수 값을 반환한다.
0.0 ≤ Math.random() < 1.0
이때, Math.random( )은 double 타입을 반환하므로
정수 난수가 필요할 경우 형변환이 필요하다.
예시 1
// 1부터 랜덤값(1 ~ 10)까지의 합계를 출력
public void method02() {
int random = (int) (Math.random() * 10 + 1);
int sum = 0;
for(int i = 1; i <= random; i++){
sum += i;
}
System.out.printf("1부터 %d까지의 합: %d\n", random, sum);
}
예시 2
// 임의의 범위 min ~ max 정수 난수
(int) (Math.random() * (max - min + 1)) + min
자주 실수하는 대표적인 유형으로
다음과 같은 형 변환 위치 실수가 있다.
(int)Math.random() * 10 // return 0
이는 형변환 (int)가 * 10 보다 먼저 수행되기 때문이다.
Math.random() 실행
0.0 ≤ 값 < 1.0
-> 0.73628...
(int) Math.random() 형 변환
(int) 0.73628...
-> int 형변환은 소수점 버림
-> 결과는 항상 0
따라서, 원하는 결과를 얻으려면
(int) (Math.random() * 10) 처럼 연산 순서를 묶어야 한다.
다음은 Math.randon( ) 메서드와 2차원 배열을 응용한 문제이다.
1부터 10사이의 랜덤값을 3행 3열의 2차원 배열에 대입하라.
단, 랜덤 값에 중복을 제거해서 대입해야한다.
다음과 같은 3 X 3 형태의 2차원 배열을 구하는것이 목표다.
1 8 9
6 4 5
2 7 3
그렇다면, 우선 해야할 것은 생성할 난수에 중복을 제거하는것이다.
바로 2차원 배열에 넣기보다는 1차원 배열을 만들어서
그 안에서 중복을 제거하여 다시 2차원 배열에 대입 하는것으로 구현했다.
public void practice2() {
int index = 0;
int[] temp = new int[9];
int[][] numbers = new int[3][3];
for(int i = 0; i < temp.length; i++) {
int random = (int) (Math.random() * 9 + 1);
temp[i] = random;
for(int j = 0; j < i; j++) {
if(temp[i] == temp[j]) {
// 해당 i값에서 중복이 발생했으므로 i값 -1 감소 후 다시 랜덤 부여
i--;
break;
}
}
}
for(int i = 0; i < numbers.length; i++) {
for(int j = 0; j < numbers[0].length; j++) {
numbers[i][j] = temp[index++];
System.out.printf("%d\t", numbers[i][j]);
}
System.out.println();
}
}