C言語関係掲示板

過去ログ

No.1344 乱数で最初の値がいつも同じになる

[戻る] [ホームページ]
No.18278

乱数で最初の値がいつも同じになる
投稿者---selvid(2004/11/20 18:57:38)


こんにちは。題名にある通りなのですが、このプログラムで実行すると
最初の値だけが何度実行されても固定されてしまう(?)のです。
日によって「5」か「3」になります。どうしてこうなるのでしょうか?
どなたかお解りの方いらっしゃいましたらレスをお願いいたします。
環境はWindowsXP、Microsoft Visual C++ 6.0です。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int i, n;

    srand((unsigned)time(NULL));

    printf("1〜6:\n");
    for ( i = 1; i <= 10; i++ ) {
        n = (int)(rand() / (RAND_MAX+1.0) * 6.0);
        ++n;
        printf("%d ", n);
    }
    printf("\n");

    return 0;
}



No.18279

Re:乱数で最初の値がいつも同じになる
投稿者---あかま(2004/11/20 19:15:29)


>こんにちは。題名にある通りなのですが、このプログラムで実行すると
>最初の値だけが何度実行されても固定されてしまう(?)のです。
BCCで実行してみましたが、たしかになんか偏るような。
連続実行してみると、最初の値が10秒ぐらいは変わらないですねぇ。
なんでだろ。
一秒単位で変わるはずですよね?


No.18297

Re:乱数で最初の値がいつも同じになる
投稿者---ニタチ(2004/11/22 10:21:29)


>連続実行してみると、最初の値が10秒ぐらいは変わらないですねぇ。
>なんでだろ。
>一秒単位で変わるはずですよね?

初めの値に規則性はありますが、ちゃんと一秒単位で変わっています。

    for ( i = 1; i <= 10; i++ ) {
        r = rand();
        n = (int)(r / (RAND_MAX+1.0) * 6.0);

        ++n;
        printf("%5d %d\n", r, n);
    }
    
以下 WindowsXP Borland C++Builder 6 で実行
約1秒刻みに5回実行した結果(初めの値のみ)
 2704 1
 2488 1
 2273 1
 2057 1
 1842 1



No.18280

Re:乱数で最初の値がいつも同じになる
投稿者---ぽへぇ(2004/11/20 20:18:55)


>環境はWindowsXP、Microsoft Visual C++ 6.0です。
今ランタイム部分のソースをみましたが、うーんって感じですね。

その環境なら

#include <windows.h>
srand(GetTickCount());

でいかがでしょう。



No.18281

Re:乱数で最初の値がいつも同じになる
投稿者---selvid(2004/11/20 21:45:58)


あかまさん、ぽへぇさん、レス有難うございます。

>>環境はWindowsXP、Microsoft Visual C++ 6.0です。
>今ランタイム部分のソースをみましたが、うーんって感じですね。
>
>その環境なら
>
>#include <windows.h>
>srand(GetTickCount());
>
>でいかがでしょう。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main(void)
{
    int i, n;

    srand(GetTickCount());
    printf("1〜6:\n");
    for ( i = 1; i <= 10; i++ ) {
        n = (int)(rand() / (RAND_MAX+1.0) * 6.0);
        ++n;
        printf("%d ", n);
    }
    printf("\n");

    return 0;
}


早速、ぽへぇさんの方法で上のようにやってみると上手くいきました。
<time.h>はもう必要ないのですね?有難うございました。
やはり環境の問題なんですか?
なにぶん初心者なもので、<windows.h>やGetTickCount()関数など初めて
目にしました。私の持っている参考書には載っていなかったです。

で、これで実行するとワークスペースのFileViewタブの所に、
「外部依存関係」というフォルダが自動的に作成されたのですが、
これは一体どういうことなのでしょう???


No.18282

Re:乱数で最初の値がいつも同じになる
投稿者---ぽへぇ(2004/11/20 22:49:55)



>なにぶん初心者なもので、<windows.h>やGetTickCount()関数など初めて
>目にしました。私の持っている参考書には載っていなかったです。
 Windowsに特化した参考書でなければ載っていないと思います。
環境依存なプログラムはあまり勧められたものではないですが。

>で、これで実行するとワークスペースのFileViewタブの所に、
>「外部依存関係」というフォルダが自動的に作成されたのですが、
>これは一体どういうことなのでしょう???
その「外部依存関係」に書かれたファイルを何か(たぶんwindows.h
でしょう)が参照している、ということです。
 そのファイル自身はワークスペースに入れられていないので
「外部依存」という表現になっています。放っておくのがいいでしょう。

>やはり環境の問題なんですか?
 件のsrandとrandを使って、selvidさんの最初のプログラムのように
すると(理論的に)nの一発目は1時間くらいは値が変わらないはずです
(いやぁ、初めて知りました^^;)
BCCでは10秒くらいというあかまさんの報告がありますからBCCの
乱数関数の中身はVC++とは異なるということでしょうね。

 自前で擬似乱数関数を用意するのもよろしいかと。
Mersenne Twisterは評判が良いようです。



No.18283

Re:乱数で最初の値がいつも同じになる
投稿者---ぽへぇ(2004/11/20 23:01:29)


別解。

srand(time(NULL));
// RAND_MAX に一番近い6の倍数
int nn = RAND_MAX / 6 * 6;
int n = (int)(rand() / (RAND_MAX+1.0) * nn) % 6;



No.18284

ありがとうございました
投稿者---selvid(2004/11/20 23:25:29)


ぽへぇさん、いろいろとアドバイスして頂き、ありがとうございました。

感謝します。