longで指定範囲の乱数

ポウラナー ヘフェ ヴァイスビア

結局、乱数が一様であれば、それを分割した部分も一様になるはずなので、基本的にはgetLong() % nで大丈夫そうです。ただ、そうするとlongの範囲が割り切れなかった部分で、乱数にムラができるので、考慮する必要があります。
で、結局そうすると、nがintの範囲ならgetInt(n)を使って、intの範囲を超えていればgetLongでn以上のものを捨てれば大丈夫じゃないかということになりました。
なので、結局こんな感じになります。

public long nextLong(Random r, long n){
    if(n <= Integer.MAX_VALUE) return r.nextInt((int)n);
    for(;;){
        long t = r.nextLong();
        if(t < 0) t -= Long.MIN_VALUE;
        if(t < n) return t;
    }
}


ということをquintiaさんから教えてもらいました。java.util.Randomですべてのlongが生成できないという問題は、メルセンヌ・ツイスターで解決。
http://materia.jp/blog/20081110.html#p02


追記。なんか勘違いがありました。結局、nextInt(int)と同じことをやればよいだけでした。

long nextLong(long n){
  long bits, value;
  do{
    bits = r.nextLong();
    if(bits < 0) bits -= Long.MIN_VALUE;
    val = bits % n;
  } while (bits - val + (n - 1);
  return val;
}