dポイントプレゼントキャンペーン実施中!

正規乱数をボックスミューらー法で発生させて、
範囲を指定して出力したいと思ってます。
プログラムを作成してみたのですが・・・
平均50で範囲を48から52にしたいのですが
たまに範囲外というか「0.0」が出力されてしまいます。
アドバイスをください

import java.util.*;
public class test2{
public static void main(String args[]){
double R,S;
double r[]=new double[200];
 double s[]=new double[200];
double s1[]=new double[200];

Random ran=new Random();
   for(int i=0;i<200;i++){
    R=ran.nextDouble();
S=50+Math.sqrt(-2*Math.log(ran.nextDouble()))*Math.cos(2*Math.PI*(ran.nextDouble()));
r[i]=R;

s1[i]=S;

if(50-2<s1[i]){
if(50+2>s1[i]){

s[i]=s1[i];



}
}
}



for(int j=0;j<150;j++){

System.out.println(s[j]);

}
}
}

お願いします

A 回答 (4件)

これは


if(50-2<s1[i]){
if(50+2>s1[i]){
のため48.0<s1[i]<52.0以外例えば
47.8や52.3のときはs[i]に0.0が代入
されているのですね。
なのでそれ以外のときは何を代入するかですが

単純に考えてその場合は出力しなければよいの
ですから
for(int j=0;j<150;j++){
if(s[j]!=0.0){//0でなければprintする。

System.out.println(s[j]);
}
}
    • good
    • 0
この回答へのお礼

なるほど!
かんたんな事でしたね!
ありがとうございました!

お礼日時:2006/07/03 16:10

こんにちは、


48~52の乱数、平均を50とすると、
1~5の乱数を作り、
47に加えれば良いのでは、ないでしょうか。
    • good
    • 0
この回答へのお礼

正規乱数で1~5というのは指定できるのでしょうか・・?
とりあえずやってみます!
ありがとございました

お礼日時:2006/07/03 16:09

>たまに範囲外というか「0.0」が出力されてしまいます。



logやcosやsqrtは、定義域にない引数を渡すとエラーになります。

また、式の途中でオーバーフローが起こる可能性もあります。

その場合、
S=50+Math.sqrt(-2*Math.log(ran.nextDouble()))*Math.cos(2*Math.PI*(ran.nextDouble()));
は実行されないか、Sはオーバーフロー値になります。

結果、
s1[i]=S;
も実行されず、s1[i]は初期値(0.0)のままになります。

なので、このままでは、たまに0.0が出ます。

S=50+Math.sqrt(-2*Math.log(ran.nextDouble()))*Math.cos(2*Math.PI*(ran.nextDouble()));

S=0
S=Math.sqrt(-2*Math.log(ran.nextDouble()))*Math.cos(2*Math.PI*(ran.nextDouble()));
S=S+50
にしてみましょう。0.0は出なくなります。但し、オーバーフローや値域エラーの場合にSは最終的に50.0になるので「50.0だけ少し多く出現する」と言う偏りが出ます。

偏りを無くすには、オーバーフローと値域のチェックを行いましょう。
    • good
    • 0
この回答へのお礼

0.0になってしまう理由がわかりました!
ありがとうございました!

お礼日時:2006/07/03 16:12

正規乱数をボックスミューらー法は知りませんが


単純に、条件に合わなくて、

s[i]=s1[i];

に行かない場合があるからでは?

if文から外れたときの値を、表示してみてはいかがでしょうか?
    • good
    • 0
この回答へのお礼

if文ではじかれた配列が0.0になるんですね!
アドバイスありがとうございました!

お礼日時:2006/07/03 16:13

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!