(1) Math.random() v.s. Random

About

Javaμ—μ„œ λ‚œμˆ˜λ₯Ό λ°œμƒμ‹œμΌœλ³΄μž. 제일 μ‰¬μš΄ 두 가지 방법이 μžˆλ‹€.

  1. java.lang.Math의 static λ©”μ†Œλ“œ random()

  2. java.util.Random 클래슀

μ—¬κΈ°μ„œ λ°œμƒλ˜λŠ” λ‚œμˆ˜λ₯Ό μ˜μ‚¬λ‚œμˆ˜(Pseudorandom Number)라고 ν•˜λŠ”λ°, λ‚œμˆ˜λŠ” μ•„λ‹ˆμ§€λ§Œ λ‚œμˆ˜λ‘œ 취급이 κ°€λŠ₯ν•œ μˆ˜μ—΄μ„ μ§€μΉ­ν•œλ‹€.

Note: λ‚œμˆ˜λ₯Ό λ°œμƒμ‹œν‚€λ €λ©΄ 초기 seed 값이 ν•„μš”ν•˜λ©°, ν•΄λ‹Ή seedλ₯Ό κΈ°μ€€μœΌλ‘œ λ‚œμˆ˜λ₯Ό λ°œμƒμ‹œν‚¨λ‹€. λ™μΌν•œ seed둜 λ‚œμˆ˜λ₯Ό μƒμ„±ν•˜λ©΄ λ‹€μŒμ— μ‹€ν–‰ν•  λ•Œλ„ λ˜‘κ°™μ€ λ‚œμˆ˜κ°€ μƒμ„±λœλ‹€.

java.lang.Math.random()

MathλŠ” java.lang νŒ¨ν‚€μ§€μ— 속해 μžˆμ–΄ λ³„λ„λ‘œ importν•  ν•„μš”κ°€ μ—†λ‹€.

Math.random()λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒμœΌλ‘œ λ‚œμˆ˜λ₯Ό 생성할 수 있으며, ν˜„μž¬ μ‹œκ°„μ„ seed둜 μ‚¬μš©ν•œλ‹€.

MathRandomTest.java
public class MathRandomTest {
    public static void main(String[] args) {
        double rand = Math.random();
        System.out.println(rand); // 0.4537741466030336
    }
}

λ²”μœ„λŠ” 0.0 ≀ Math.random() < 1.0이닀.

μ •μˆ˜ λ§Œλ“€κΈ°

μ •μˆ˜ νƒ€μž…μ˜ λ‚œμˆ˜κ°€ ν•„μš”ν•  λ•Œλ„ μžˆλ‹€.

예λ₯Ό λ“€μ–΄ 0 이상 9 μ΄ν•˜μ˜ λ‚œμˆ˜κ°€ ν•„μš”ν•˜λ‹€λ©΄ 10을 κ³±ν•΄μ£Όκ³  int νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ν•˜λ©΄ λœλ‹€.

MathRandomIntegerTest.java
public class MathRandomIntegerTest {
    public static void main(String[] args) {
        int rand = (int) (Math.random() * 10);
        System.out.println(rand); // 0.4537741466030336
    }
}

java.util.Random 클래슀

Random ν΄λž˜μŠ€λŠ” java.util νŒ¨ν‚€μ§€μ— μ†ν•΄μžˆμœΌλ―€λ‘œ importν•΄μ•Όν•œλ‹€.

UtilRandomTest.java
import java.util.Random;

public class UtilRandomTest {
    public static void main(String[] args) {
        // 1. Random 객체 생성
        Random rand = new Random();
        
        // 2. Random 객체 생성 (μƒμ„±μžλ‘œ seed 전달)
        long seed = System.currentTimeMillis();
        Random rand2 = new Random(seed);
        
        // 3. Random 객체 생성 (setSeet() λ©”μ†Œλ“œλ‘œ seed 전달)
        Random rand3 = new Random();
        rand3.setSeed(System.currentTimeMillis());
        
        int intRand = rand.nextInt(10); // 7
    }
}
  • Math.random()κ³Ό 달리 λ¨Όμ € Random 객체λ₯Ό 생성해야 ν•œλ‹€.

  • seedλ₯Ό μ„€μ •ν•  μˆ˜λ„ μžˆλ‹€. μƒμ„±μžμ— seedλ₯Ό μ „λ‹¬ν•˜κ±°λ‚˜, setSeed() λ©”μ†Œλ“œλ‘œ μ„€μ •ν•  수 μžˆλ‹€.

  • λ‹€μ–‘ν•œ λ‚œμˆ˜ λ°œμƒ λ©”μ†Œλ“œλ₯Ό μ§€μ›ν•œλ‹€.

    • nextBoolean(), nextInt(), nextLong(), nextInt(int n), nextFloat(), nextDouble(), nextGaussian()

그럼 뭘 μ¨μ•Όλ κΉŒ?

Stack Overflow의 ν•œ 글에 λ”°λ₯΄λ©΄ Random.nextInt(n)κ°€ Math.random() * n보닀 더 효율적이고 덜 편ν–₯적(biased)이라고 ν•œλ‹€.

Math.random()은 λ‚΄λΆ€μ μœΌλ‘œ Random.nextDouble()을 μ‚¬μš©ν•œλ‹€. Random.nextDouble()은 Random.next() ν•¨μˆ˜λ₯Ό 두 번 ν˜ΈμΆœν•΄μ„œ κ°€μˆ˜λΆ€(mantissa)에 κ· μΌν•˜κ²Œ λΆ„ν¬λœ λΉ„νŠΈλ₯Ό κ°–λŠ” double을 μƒμ„±ν•˜λ―€λ‘œ 0λΆ€ν„° 1 - 2^(-53) λ²”μœ„μ—μ„œ 더 κ· μΌν•˜κ²Œ 값을 κ°€μ Έμ˜¨λ‹€κ³  ν•œλ‹€.

Random.nextInt(n)은 Random.next()λ₯Ό 평균 2번 미만 μ‚¬μš©ν•œλ‹€. ν•œ 번 ν˜ΈμΆœν•˜κ³ , λ§Œμ•½ 값이 MAX_INT보닀 μž‘μ€ κ°€μž₯ 큰 n의 λ°°μˆ˜λ³΄λ‹€ 크닀면 λ‹€μ‹œ μ‹œλ„ν•˜κ³ , μ•„λ‹ˆλΌλ©΄ κ°’ mod n을 λ°˜ν™˜ν•œλ‹€. (μ΄λ ‡κ²Œ ν•¨μœΌλ‘œμ¨ MAX_INT보닀 μž‘μ€ κ°€μž₯ 큰 n의 λ°°μˆ˜λ³΄λ‹€ 큰 값듀이 λ‚˜μ˜€μ§€ μ•Šλ„λ‘ ν•˜μ—¬, κ°’μ˜ 편ν–₯성을 쀄인닀) κ·Έλž˜μ„œ 0λΆ€ν„° n-1의 λ²”μœ„μ—μ„œ κ· μΌν•˜κ²Œ λΆ„ν¬λœ 값을 λ°˜ν™˜ν•œλ‹€.

...

Math.random()은 μ•½ 두 배의 처리λ₯Ό ν•„μš”λ‘œ ν•œλ‹€.

결둠만 따져보면 Math.random()보닀 Random.nextInt()κ°€ 더 νš¨μœ¨μ μ΄λΌλŠ” 것이닀.

그리고 또 μ€‘μš”ν•œ 차이점이 μžˆλŠ”λ° Random.nextInt(n)μ—λŠ” seed 값을 전달할 수 μžˆλ‹€λŠ” 것이닀. λ™μΌν•œ seedλ₯Ό 가진 Random 객체λ₯Ό μ—¬λŸ¬ 생성할 수 μžˆλ‹€. Math.random()μœΌλ‘œλŠ” λΆˆκ°€λŠ₯ν•˜λ‹€.

More on the matter

REF

Last updated