- ベストアンサー
long型のランダムな値を返す方法
C言語について質問させて頂きます。 私は今、0以上50万以下(上限は50万以上ならどんな値でもかまいません)の範囲でランダムに整数を得たいと考えております。 #include <stdlib.h>のint rand(void)は0以上の乱数を返してくれますが、返す値はintの範囲内(?)なので、要望に合っておりません。 そこで、long型のランダムな値を得たいと思っております。 一体、どのような関数またはアルゴリズムを使えば、望むように出来るのでしょうか? 是非、お教えください。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
手抜きで考えるなら ランタイムのrandが 0から32767までを返すなら randを値を2つ取って一方は4ビットシフトして0x7fff0まで作ります 他方の下位4ビットとの合計をします この値から 希望の50万での剰余を求めるとか long myRand( long limit ) { long nRes[2]; nRes[0] = rnad() << 4; nRes[1] = rand(); nRes[0] |= nRes[1] & 0x0F; return nRes[0] % limit; }
その他の回答 (8)
- D-Matsu
- ベストアンサー率45% (1080/2394)
回答というより補足説明っぽいですが。 昨今のコンパイラではintとlongはたいてい一緒なので、No.1の回答ままでもご期待の動作は得られるかと思います。 が、int型の大きさはコンパイラ依存なのであまり望ましくないのも事実ですね。キャストをlongにしてしまえば確実になります。 なおrand()の返す最大値はlimits.hのRAND_MAXで規定されています。大抵はshort、もしくはunsigned shortの最大値になっているでしょう。
お礼
説明を有難うございます。 limits.hをまた調べてみます。
- titokani
- ベストアンサー率19% (341/1726)
#7です。訂正 元の値 剰余 0 0 1 1 2 2 3 0 でした。 多くなるのは0の場合ですね。
お礼
丁寧な回答を有難うございます。 どの値が出る回数が最も多いかはあまり気にしておりませんが、頻度については確認しておこうと思います。
- titokani
- ベストアンサー率19% (341/1726)
>rand()+rand() で、0~2*RAND_MAXまでの値が得られると思います。。 この方法だと、RAND_MAX+1の値が一番多く出ることになってしまいます。 サイコロを2つ振ったときの合計は7が一番多くなるのと一緒ですね。 >この値から 希望の50万での剰余を求めるとか これも微妙に良くないです。 例えば、0~3までの乱数発生器があったとして、0~2までの乱数が欲しい時、3での剰余を使うと 元の値 剰余 0 0 1 1 2 2 3 1 となって、1が出る確率が多くなります。 どうせ手抜きでも、目的の値より大きな値がでたら、もう一回やりなおしのほうがいいかと思います。
- titokani
- ベストアンサー率19% (341/1726)
それなりにまともな質の乱数が欲しいのなら、調べれば乱数アルゴリズムはみつかりますから、それに基づいて独自に実装するのがいいと思います。 乱数の質にこだわらないのなら、rand()を2回使えばいいと思います。
- JaritenCat
- ベストアンサー率37% (122/322)
rand()+rand() で、0~2*RAND_MAXまでの値が得られると思います。。
お礼
小技なアイデアをどうも有り難うございます。 その作戦に気づきませんでした。 早速longの範囲でのランダム値が得られるようにやってみます。
- koko_u_
- ベストアンサー率18% (459/2509)
random() とか使えれば、それを利用するのがよい。精度的な意味でも。
- Tacosan
- ベストアンサー率23% (3656/15482)
まじめにいくならどこかから Mersenne Twister でもひろってくる.
- yaemon_2006
- ベストアンサー率22% (50/220)
0~n の乱数 (int)((n + 1) * (rand() / (RAND_MAX + 1.0))
お礼
int型では希望の範囲の値が得られないんですけど、、 回答は有難うございます。
お礼
ビット演算を利用するという私にとっては予想外な発想でのアルゴリズムをどうも有り難うございます。いい事を学べました。 このアルゴリズムを使うと100万でも1000万でもいけそうですね。 是非、活用させていただきます。