• ベストアンサー

0から1までの乱数(実数値)を発生させるのと、ある確率の時に処理をさせたい。

1 #include <stdio.h> 2 #include <time.h> 3 #include <stdlib.h> 4 #define P 0.05 5 int main(void) 6 { 7 int abc; 8 double x; 9 srand(time(NULL)); 10 x = (double)rand()/RAND_MAX; 11 if(x > P){ 12 abc = 1; 13 } ・・・ (1)0から1までのランダムな実数値を10行目で発生させているつもりですが、あまりきざみが良くない?とこ耳にはさんだので0から1までの最もいいと思われるランダムな実数値の発生を教えてもらえないでしょうか? (2)11行目で約1/20000の確率でabcに1を代入したいのですが、上記のプログラムをどのように改良すればよろしいでしょうか? どちらか片方でもアドバイス頂ければ幸いなので、お手数ですがよろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

(1) きざみがよくないのはintがカバーする範囲と doubleがカバーする範囲ではdoubleの方が大きいからです。 doubleは浮動小数点8バイトintは整数値4バイト(処理系依存)ですし ※doubleは仮数部52ビット(IEEE754の場合) 当然です。ましてやVC++.net2003の場合RAND_MAXは0x7fff(2バイト以下)で 定義されているので尚更です。 しかしよほど精度を必要とする科学技術計算でもしないのなら 気にならないとおもいますが。 (2) #define RANDOM(x) (rand()%(x)) として定義するのが一般的です。 RANDOM(10)とすると0~9までの整数が返ります。 RANDOM(20000)とすると0~19999が返ってきます。 とはいっても厳密にはRAND_MAXに影響するので1/20000ではありませんし ANSI Cにはいっているのはrand()ぐらいしかあいません。 しかし相当な精度を必要としないのであれば普通は十分です。 自分でランダムな数値の発生させたいなら アルゴリズムがのっている http://www5.airnet.ne.jp/tomy/cpro/science.htm を参考にしてください。

20centuryboy
質問者

お礼

お礼の返事が遅くなってすみませんでした。 (1)のきざみの話ですが、doubleの方がより細かい乱数をきざめることがよく分かりました。 確かにWindowsとUNIX系だとRAND_MAXの定義違いますよね。もう一度確認しておきます。 (2)の関数マクロを使って定義するのは非常に参考になりました。 まだホームページは見てないのでこれから見て来ます。 また何か分からないことがあったらよろしくお願いします。どうもご親切にありがとうございました。

その他の回答 (3)

回答No.4

for(i=0;i<1000000;i++){ if(x > P){ abc++; } } 上では,「計算を1000000回行って,その計算内で,x>Pならabcに1を足していく」という解釈ですよ. ********************************************** >1/20000の確率でabcに+1していきたい xが0~1の範囲内で同じ確率で出る(はず)ですので, if文の箇所はやはり if(x<=0.001*P) {abc=1;} でいいと思われます. とりあえず, if(x<=0.5) {abc=1;} あたりから始めてみてはいかがですか?

20centuryboy
質問者

お礼

お礼の返事が遅くなりすみませんでした。 >>上では,「計算を1000000回行って,その計算内で,x>Pならabcに1を足していく」という解釈ですよ. その通りなのですが、1000000回ループさせる内、数回if文を満たして実行させて、結果的に1/20000位の確率でabcに値が+されているという実験をしたかったのですがなかなかうまくいきませんでした。 とりあえずif(x<=0.5) {abc=1;}から始めてみたいと思います。 度々ご親切に回答して頂きありがとうございました。

noname#30727
noname#30727
回答No.3

(1)rand()を複数回使用する。 例えば12桁くらい欲しければ、 x = rand() % 1000 / 1e3 + rand() % 1000 / 1e6 + rand() % 1000 / 1e9 + rand() % 1000 / 1e12;

20centuryboy
質問者

お礼

お礼の返事が遅くなってすみませんでした。 きざみの話ですが分かりやすい実例を上げて頂きありがとうございました。 再びプログラムに取り掛かっているのですが、試して見たいと思います。 また何かわからないことがありましたら宜しくお願い致します。 どうもご親切にありがとうございました。

回答No.1

(1)  1を含めるのでしょうか? x=rand()/(1.0+RAND_MAX);←0<=x<1 x=rand()/(RAND_MAX);←0<=x<=1 20centuryboyさんので問題ないと思いますが…. (2) 1/20000の確率のところが?です. #define P 0.05と,11行目のPとの関連は? これだと「0.05よりもxが大きければ,abc=1」と解釈できますよ. if(x<=0.001*P) {abc=1;} ではだめですか? 「xが1/20000以下であればabcに1を代入する」 という意味ですが….

20centuryboy
質問者

補足

早速の回答ありがとうございます。 情報が少なくてすみません、(1)では0<x<1の範囲で実数値を発生させたいと考えていました。回答とても参考になりました。またsrandに与える種次第で、xに入る値が変わってくると思うので、他にいい種があるのかなーと思って質問しました。ただ私があまり理解していないので質問内容が不明な点が多いと思うのですが、頭を整理すると(2)を一番知りたいと思っているので(2)の方を教えていただけないでしょうか?ご迷惑かけてすみません。 (2)では 1 #include <stdio.h> 2 #include <time.h> 3 #include <stdlib.h> 4 #define P 0.05 5 int main(void) 6 { 7 int i,abc; 8 double x; 9 srand(time(NULL)); 10 x = (double)rand()/RAND_MAX; 11 for(i=0;i<1000000;i++){ 12 if(x > P){ 13 abc++; 14 } 15} ・・・ 11から14行目の処理で1/20000の確率でabcに+1していきたいと思っているのですが(for文が抜けてました)、Pとxの調整次第、もしくは別の条件文で可能なのかと考えています。私のプログラムだとどのくらいの確率でabcに++していくのか分からないので。後からいろいろ確率を変えてみてそれを1/10000、1/20000、・・・のそれぞれの確率でabcがどのように変わったか表にまとめていみたいと思っています。 再度すみませんがアドバイスをお願いいたします。

関連するQ&A

  • 乱数発生

    #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) {int y, m, l; srand( (unsigned)time( NULL ) ); y=rand() % 2500 + 1600; m=rand() % 12 + 1; l=rand() % 29 + 1; printf("西暦%d年%d月%d日",y,m,l); return(0); }今回は乱数発生でランダムにだされた西暦年月日をつくりましたが、y=rand() % 2500 + 1600; というのがありこれはyという乱数が2500以下1600以上という意味なのですがなぜかプログラムを実行しても3000いくつとか4000いくつなんてのもでてきます。m=rand() % 12 + 1;はちゃんと12以下1以上でできるのですがなぜですか?本当にわかりません。是非だれか教えてください。

  • 乱数について

    Visual Studio2008を使っています。 #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int i; srand(time(NULL)); i=rand(); printf("%d\n",i); return 0; } 乱数を作るために上のようなプログラミングを作りました。 これを「ソリューションのビルド」すると 【warning C4244: '引数' : 'time_t' から 'unsigned int' への変換です。データが失われる可能性があります。】 と出ます。 このまま行っても乱数が出来るのですが どうしたらいいのでしょうか? 8行目を srand(time_t(NULL)); srand((unsigned)time(NULL)); と変えればいいのでしょうか? time_tでやると乱数が同じ値しか出てきません。 教えてください。

  • C++で乱数を重複しないように発生させる

    C++で乱数を重複しないように発生させるようにプログラムを変更しろと言われたのですが、できません。 教えていただきたいです。 #include<iostream> #include<cstdlib> #include<cstring> #include<ctime> using namespace std; int main() { int i,n; int *p; cout<<"何個記憶しますか?"<<endl; cin>>n; p=new int[n]; if(p==NULL){ cout<<"記憶域の確保に失敗しました。"<<endl; return 1; } srand((unsigned)time(NULL)); rand(); i=0; while(i<n){ p[i]=1+(int)((double)rand()/(RAND_MAX+1.0)*75); if(p[i]==p[i]) cout<<"p["<<i<<"]の値"<<p[i]<<endl; i++; } delete[] p; return 0; }

  • 乱数

    #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void) { double n,end; printf("いくつ以上の値が出たら終了しますか?:"); scanf("%lf",&end); srand((unsigned)time(NULL)); for( ; ; ){ n=(double)rand(); printf("%f\n",n); if(n>=end) break; } return 0; } これなんですが、このまま実行すると.00000になってしまいます。 自分的には0.~にしたいのですが、どう変えればいいでしょうか? 回答お願いします。

  • 毎回違う乱数を生成するにはどうしたらいいでしょうか

    C言語の初心者です。よろしくお願いいたします! 乱数に関する質問:毎回違う乱数を生成するにはどうすればいいでしょうか。 学校の講義の中に  >>time() は1970 年1 月1 日0 時0 分(標準時)からの経過秒数を返 すため,1 秒以内に何度も実行すると,同じ数字で乱数を初期化す ることになり,結果も同じになってしまう. という記述がありますが、時間を置いてから、実行しても同じ結果となりました。 その一 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> int main(void) { double x,y; int i,index=0; double a,n; printf("How many trials?..."); scanf("%lf",&n); for (i=0;i<n;i++) { x=rand()/(RAND_MAX+1.0); y=rand()/(RAND_MAX+1.0); if((x*x+y*y)<1) index++;} a=4*index/n; printf("Result is %.2f(%.2f)",a,sin(-a)); return 0; } その二 #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int a; srand((unsigned)time(NULL)); a=(int)(rand()/(RAND_MAX+1.0)*10); printf("%d\n",a); return 0; } お忙しい中、教えていただけたらうれしいです。

  • 乱数について

    プログラミングの授業で、各種ソートのプログラムを勉強しました。 srand (99);でランダムに数字を作っていると教わったのですが、この中の数字もランダムにしたい場合、どのようなプログラムに変えればいいのでしょうか? また、括弧内の数字で、どのようにランダムに数字をはき出しているのか知りたいです。 ~time.c~ #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX 250000 void insert_sort(int x[], int n); main() { int i , x[MAX] , n ; time_t start , end ; //列配列の選択 srand (99); for (i = 0 ; i<MAX ; i++) x[i] =rand() % MAX; n = MAX; start =clock(); //測定対象プログラム insert_sort (x ,n); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("%f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~insert.c~ void insert_sort(int x[], int n) { int i, j, tmp; for(i=1;i<n;i++){ for(j=i;j>0;j--){ if(x[j]<x[j-1]){ tmp = x[j]; x[j]=x[j-1]; x[j-1]=tmp; } else{ break; } } } }

  • 標準正規分布の乱数

    RAND()関数は ((double)rand() / (1.0 + RAND_MAX))と定義します。 中心極限定理により、一様乱数を足し合わせると正規分布に近づくことから、 x = 分散 * (Σ[1~12]RAND() - 6) + 平均 で正規乱数が作れる。標準正規分布は分散1、平均0なのでその乱数は x = Σ[1~12]RAND() - 6 ですよね。この乱数を例えば100個羅列するにはどうしたらいいのでしょうか? もし間違ってたら指摘してください。 参考文献「Cによるシミュレーションプログラム 石川宏」 #include <stdio.h> #include <stdlib.h> #define RAND() ((double)rand() / (1.0 + RAND_MAX)) #define NUMBER 10000 /* 発生させる乱数の数 */ main(void) { int j; double u, x; srand(5); for (j = 0; j <= 11; j++) { u = u + RAND(); } x = u - 6.0; }

  • 乱数について

    C の入門書を1冊読み終え、簡単なプログラムを作成しようとしているのですが、 早速分からないことが出たので教えて頂ければと思います。 --------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { int num; int i = 0; while( i < 4 ){ srand(time(NULL)); num = rand()%100; printf("%d\n", num); i++; } return 0; } --------------------------------------------- 上記を実行したのですが、秒数を乱数の種としているため4回とも同じ値を取得してしまいます。 より高精度に秒数を取得することは可能でしょうか? もしくはこのようなかたちで4回ともに異なる数を得ることが出来る方法がありましたら教えて頂きたいと思います。

  • 正規乱数をエクセルに

    正規乱数を発生させるプログラムを作ったのですが、これをエクセルに出力させるにはどのようにすればよいのでしょうか?すみませんが教えてください(__) #include<stdio.h> #include<stdlib.h> #include<math.h> void ran(double,double,double *); void main(void) {   int i;   double x;   for(i=0;i<1000;i++){     ran(1.0,0.0,&x);       printf("%f\n",x);      } } void ran(double sig,double m,double *x) {   double r1,r2;   r1=rand()/32767.1;   r2=rand()/32767.1;   *x=sig*sqrt(-2*log(r1))*sin(2*3.141592*r2)+m; }

  • 乱数について・・・

    (1)1,2,3,4の整数のどれかを乱数で発生させる方法 (2)0~1までの実数を発生させる方法 を教えていただけないでしょうか?(a.outするたびに値が変わってほしいです。) ※一応、下のプログラムにあるように実行するたびに違う乱数がanswerに入るようにはできたのですが、いまいち理解できていません。軽い説明や参考URLなども教えてもらえたら助かります。 よろしくお願いします。 #include<time.h> int main() { unsigned short time_a,time_b; unsigned long answer; time_a = time(NULL); time_b = time_a; srand(time_b); answer = rand(); printf("答えは = %d\n",answer); }

専門家に質問してみよう