• 締切済み

Random#nextInt(int n)の実装

Java 2 (1.4) のドキュメントによれば、java.util.Random#nextInt(int n) の実装は public int nextInt(int n) { if (n<=0) throw new IllegalArgumentException("n must be positive"); if ((n & -n) == n) // i.e., n is a power of 2 return (int)((n * (long)next(31)) >> 31); int bits, val; do { bits = next(31); val = bits % n; } while(bits - val + (n-1) < 0); return val; } となっているようですが、  return (int) (getDouble() * n) ; // もっとも簡単な実装 ではないのは何故ですか。精度上の問題があるのでしょうか?

  • Java
  • 回答数1
  • ありがとう数1

みんなの回答

  • Werner
  • ベストアンサー率53% (395/735)
回答No.1

>  return (int) (getDouble() * n) ; // もっとも簡単な実装 > ではないのは何故ですか。精度上の問題があるのでしょうか? getDoubleって乱数を返すんだっけ? 調べたところ、乱数を取得できるのはnextDoubleのようなので nextDoubleの間違いだと解釈しますね。 まずその方法には、得られる乱数がちゃんと一様分布しないという問題点があります。 nextDoubleは2の53乗通りの値を均等な確率で生成するので、 2の53乗を割り切ることができない値をnとすると必ず出現確率が偏ります。 あとは、その記述は書くのが楽なだけで、 nextDouble()内での2回のnextの呼び出しやシフト演算や除算や型変換、 そして最後のdoubleからintへの型変換など無駄な処理が多いです。

関連するQ&A

  • 乱数の作成について(初心者)

    Java初心者です。 -9から2の乱数を作成したのですが、乱数の出る確立が揃えられなくて困ってます。 どなたかお願いします。 import java.util.Random; class Rando2{ public static void main(String[] args){ Random x=new Random(); //-9から2の中から選びたい int n=x.nextInt(10); int f=x.nextInt(2);//0ならマイナスをつける if(2<n) n=-n;//-9から-3の作成(1/10の確立) else//-2から2の作成(1/20の確立) if(f==0) n=-n; System.out.print("あなたの好きな整数は"+n+"ですね?"); } }

    • ベストアンサー
    • Java
  • Randomクラスを使い同じ値をもつことがないように

    するには? サンプルコードをどう改良したらいいですか 例えば{1,3,5,5,3,2}の連続した5とならないようにするには? import java.util.*; class Sample6_9{ public static void main(String args[]){ Scanner std = new Scanner(System.in); Random rand = new Random(); System.out.print("要素数:"); int n = std.nextInt(); int[]a = new int[n]; for(int i=0;i<n;i++){ a[i] = 1+rand.nextInt(10); System.out.println("a["+i+"]="+a[i]); } } }

  • 逆コンパイルの見方について(再度)

    Jad v1.5.8e.で逆コンパイルしています。下段のParseException e;をどう理解していいか分かりません。恐らくsdfFrom.parse(val)との関係だと思うのですが public class Formatter { public Formatter() { } public static String convDateFormat(String val, String formatFrom, String formatTo) throws IllegalArgumentException { SimpleDateFormat sdfFrom; SimpleDateFormat sdfTo; if(val == null || formatFrom == null || formatTo == null) { throw new IllegalArgumentException(); } sdfFrom = Util.getSDF(formatFrom); sdfTo = Util.getSDF(formatTo); sdfFrom.setLenient(false); sdfTo.setLenient(false); return sdfTo.format(sdfFrom.parse(val)); ParseException e; e; return val; } 何卒、宜しく御願いします。

    • ベストアンサー
    • Java
  • C言語 unsigned 表示

    #include<stdio.h> int count_bits(unsigned x){ int count=0; while(x){ if(x&1U){ count++; } x>>=1; } return count; } int int_bits(void){ return(count_bits(~0U)); } unsigned rrotate(unsigned x1 ,int n){ int bits=int_bits(); n%=bits; return(n? (x1>>n)|(x1<<(bits-n)):x1); } int main (void){ unsigned nx,b; b=rrotate(nx,2); printf("%u\n",b); return(0); } 3221225476や1073741829と表示されることがあります。 入力値を4で割った数を表示するには、どうしたらよいでしょう・ 御指摘お願いします。

  • JAVA初心者です。

    以下の文法でコンパイルエラーが出ます。 添削をお願いします。 import java.util.Random; public class Test{ public static void main(String[] args){ int n; for (n = 0; n < 200; n++){ int i; for (i = 0; i < 38; i++) { Random rnd = new Random(); int ran = rnd.nextInt(10); System.out.print(ran); System.out.print(" "); for (t = 0; t < 200; t++) } System.out.println(); } } }

    • ベストアンサー
    • Java
  • 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。

    JAVAの練習問題でわからなくて困っています 以下は線形探索のプログラムで、このプログラムを改良して、 要素数が10の配列で、乱数0~9の値が重複しないようにする方法がわからなくて困っています。 以下のような簡単なプログラムでできる方法で行いたいです。 どなたか答えまたはヒントを下さい、お願いします。 ------------------------------------------------------------ import java.util.Random; import java.util.Scanner; public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); final int n = 10; //要素数 int[] a = new int[n]; //配列を宣言 for (int j = 0; j < n;) a[j] = rand.nextInt(10); System.out.print("配列aの全要素の値\n{ "); for (int j = 0; j < n; j++) System.out.print(a[j] + " "); System.out.println("}"); System.out.print("探す数値 : "); int key = stdIn.nextInt(); int i; for (i = 0; i < n; i++) if (a[i] == key) break; if (i < n) //探索成功 System.out.println("それはa[" + i + "]にあります。"); else //探索失敗 System.out.println("それはありません。"); } }

  • JAVAで配列を使って * を縦向きのグラフで表示したいです。

    JAVAの勉強をしています。 このプログラムは配列に乱数を生成して * を 横向きにするプログラムです。 練習問題で、以下のプログラムを書き換えて、* を縦向きのグラフで表示する問題なのですが、解く方法がわかりません。 どなたか答えもしくはヒントを下さい。 よろしくお願いします。 import java.util.Random; import java.util.Scanner; public class Test06_04 { public static void main (String[] args) { Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数 : "); int n = stdIn.nextInt(); //要素数を読み込む int[] a = new int[n]; //配列を生成 for (int i = 0; i < n; i++) { a[i] = 1+ rand.nextInt(10); } for (int i = 0; i < n; i++) { System.out.print("a[" + i + "] : "); for (int j = 0; j < a[i]; j++) System.out.print('*'); System.out.println(); } } }

    • ベストアンサー
    • Java
  • javaのプログラム

    int型の配列の各要素に1~10の乱数を代入し、各要素の値を縦向きの*のグラフで表示するプログラムを作っているのですが、結果がランダムででるので、自分の書いたプログラムが正しいのかわかりません。ソースを載せますので合っているのか間違っているか教えて下さい。もし間違っているならどこが間違いなのか教えていただけると嬉しいです。よろしくお願いします。 ●ソース import java.util.Random; import java.util.Scanner; class Graph { public static void main(String[] args){ Random rand = new Random(); Scanner stdIn = new Scanner(System.in); System.out.print("要素数:"); int n = stdIn.nextInt(); int a[] = new int[n]; for (int i = 0; i < n; i++) a[i] = 1 + rand.nextInt(10); for (int i = 1; i <= 10; i++){ for (int j = 0; j < n; j++) if (a[j] <= i) System.out.print("* "); else System.out.print(" "); System.out.println(); } } } ●実行例 要素数:12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

    • ベストアンサー
    • Java
  • JDK1.1.7 と JDK1.3.1 の違い。。。

    はじめて質問いたします。 現在、JDK1.1.7 で開発したアプレットがあるのですが、 この中で、java.awt.Choice を未選択状態にする為に select(-1);  としている個所があります。 このアプレットをJavaPlug-in1.3.1 を使用して実行すると、IllegalArgumentException が発生してしまいます。 そこで、1.1.7 と 1.3.1 のソースコードを比べてみると、確かに、1.3.1 では、 select(-1) は認めていないようです。 --- JDK1.1.7 の java.awt.Choice の実装 ---> public void select(int pos) {   if (pos >= pItems.size()) {     throw new IllegalArgumentException("illegal Choice item position: " + pos);   }     :     : } <--- JDK1.1.7 --- --- JDK1.3.1 の java.awt.Choice の実装 ---> public synchronized void select(int pos) {   if ((pos >= pItems.size()) || (pos < 0)) {     <--- 違いはここだけ。。。     throw new IllegalArgumentException("illegal Choice item position: " + pos);   }     :     : } <--- JDK1.3.1 --- う~ん、まさしく、-1 を拒否していますね。 何故、このような実装の違いが出ているのでしょうか? (私的には、Java2開発者の気まぐれなのではと考えてしまいます。。) また、このアプレットを最小限の修正で1.3.1 でも正常に動作するようにしたいの ですが、1.3.1 の java.awt.Choice では未選択状態にする事は不可能なのでしょうか? ご存知の方がおられましたら、是非、お教え頂きたいと思います。 よろしくお願い致します。

    • ベストアンサー
    • Java
  • java eclipse do-while文

    計算問題のプログラムです。No…0を選択したときにwhile文から抜け出したいです。 抜け出せない原因と解決方法(プログラム)を教えていただけるとありがたいです。 package lesson5; import java.util.Random; import java.util.Scanner; public class MentalArithmetic { static Scanner stdIn = new Scanner(System.in); static boolean confirmRetry(){ int cont; do{ System.out.print("もう一度?<Yes・・・1/No・・・0> : "); cont = stdIn.nextInt(); }while (cont != 0 && cont != 1); return cont ==1; } static void mondai1(){ Random rand = new Random(); do{ int p = rand.nextInt(900) + 100; int q = rand.nextInt(900) + 100; int r = rand.nextInt(900) + 100; while(true){ System.out.println(p + "+" + q + "+" + r + " = " ); int k = stdIn.nextInt(); // if(k == p + q + r) // break; System.out.println("違いますよ!!"); } }while (confirmRetry()); } public static void main(String[] args) { System.out.println("暗算力トレーニング!!"); while (true) { mondai1(); } } }

専門家に質問してみよう