- ベストアンサー
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を代入したいのですが、上記のプログラムをどのように改良すればよろしいでしょうか? どちらか片方でもアドバイス頂ければ幸いなので、お手数ですがよろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
(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 を参考にしてください。
その他の回答 (3)
- graduate_student
- ベストアンサー率22% (162/733)
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;} あたりから始めてみてはいかがですか?
お礼
お礼の返事が遅くなりすみませんでした。 >>上では,「計算を1000000回行って,その計算内で,x>Pならabcに1を足していく」という解釈ですよ. その通りなのですが、1000000回ループさせる内、数回if文を満たして実行させて、結果的に1/20000位の確率でabcに値が+されているという実験をしたかったのですがなかなかうまくいきませんでした。 とりあえずif(x<=0.5) {abc=1;}から始めてみたいと思います。 度々ご親切に回答して頂きありがとうございました。
(1)rand()を複数回使用する。 例えば12桁くらい欲しければ、 x = rand() % 1000 / 1e3 + rand() % 1000 / 1e6 + rand() % 1000 / 1e9 + rand() % 1000 / 1e12;
お礼
お礼の返事が遅くなってすみませんでした。 きざみの話ですが分かりやすい実例を上げて頂きありがとうございました。 再びプログラムに取り掛かっているのですが、試して見たいと思います。 また何かわからないことがありましたら宜しくお願い致します。 どうもご親切にありがとうございました。
- graduate_student
- ベストアンサー率22% (162/733)
(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を代入する」 という意味ですが….
補足
早速の回答ありがとうございます。 情報が少なくてすみません、(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がどのように変わったか表にまとめていみたいと思っています。 再度すみませんがアドバイスをお願いいたします。
お礼
お礼の返事が遅くなってすみませんでした。 (1)のきざみの話ですが、doubleの方がより細かい乱数をきざめることがよく分かりました。 確かにWindowsとUNIX系だとRAND_MAXの定義違いますよね。もう一度確認しておきます。 (2)の関数マクロを使って定義するのは非常に参考になりました。 まだホームページは見てないのでこれから見て来ます。 また何か分からないことがあったらよろしくお願いします。どうもご親切にありがとうございました。