JavaBookStudy / JavaBook

책읽기 스터디
https://javabookstudy.github.io/
Apache License 2.0
19 stars 2 forks source link

[Effective Java] Item 59. 랜덤 함수 #35

Closed kjsu0209 closed 3 years ago

kjsu0209 commented 3 years ago
static Random rnd = new Random();

static int random(int n){
    return Math.abs(rnd.nextInt()) % n;
}

책에서는 위 코드가 세 가지 문제를 가지고 있다고 합니다.

  1. n이 크지 않은 2의 제곱수라면 같은 수열이 반복된다.
  2. n이 2의 제곱수가 아니라면 몇몇 숫자가 평균적으로 더 자주 반환된다.
  3. n값이 크고 2번의 경우라면 더 자주 같은 숫자가 반환된다.

이런 문제가 2의 보수 계산과 관련이 있다고 하는데 왜 생길까요?

daebalprime commented 3 years ago

2의 보수의 경우에는 Math.abs(Integer.MIN_VALUE)==Integer.MIN_VALUE의 원인이지 언급하신 문제의 원인은 아닙니다. 2의 보수에서 부호를 바꾸고자 할 때 비트를 반전한 후 1을 더해주는데, Integer.MIN_VALUE = 1000....000인데 부호를 반전하면 0111...111이고 여기에 1을 더해주면 다시 1000...000이 됩니다.

참고하기 : Math.abs 구현 public static int abs(int a) { return (a < 0) ? -a : a; }

위 코드가 가진 세 가지 문제점에 대한 내용은 스택오버플로우를 참조하시면 좋겠습니다. (저는 수학을 못하고 정수론을 몰라요...)https://stackoverflow.com/questions/27779177/effective-java-item-47-know-and-use-your-libraries-flawed-random-integer-meth