乱数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Sera
記事: 31
登録日時: 10年前

乱数について

#1

投稿記事 by Sera » 10年前

皆さん、新年明けましておめでとうございますヽ(*´∀`)ノ

早速なんですが、乱数に関する質問です。(`・ω・´)

先日、あるC言語に関する書籍を買ったのですが、その中に、

1から999までを指定するにはsrand関数で乱数を初期化してあまりを出すためにrand % xにすればいい。

などと意味のわからないことばかりでした。。。

サンプルソースを一応書いておきます

コード:

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

int main() {
    int i;
    srand( (unsigned int)time(NULL) );
    for(i = 0; i < 10;i++){
        printf("%d\n",rand()%1000 + 1);
    }
    return 0;
}
もうぶっちゃけて言うとほとんど理解できていないんですが
srand( (unsigned int)time(NULL) );

rand()%1000 + 1
の意味をよかったら詳しく教えてください・゚・(ノД`)・゚・

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 乱数について

#2

投稿記事 by softya(ソフト屋) » 10年前

あけまして、おめでとうございます。

塊で考えているようなので、もっと分解して考えてみましょうか。
理解するためには分解しないといけないですよ。

と言うことで逆質問してみます。
これは何でしょうか? 説明してみてください。
(1) srand
(2) time(NULL)
(3) rand()
(4) %1000
です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#3

投稿記事 by Sera » 10年前

softya(ソフト屋) さんが書きました:あけまして、おめでとうございます。

塊で考えているようなので、もっと分解して考えてみましょうか。
理解するためには分解しないといけないですよ。

と言うことで逆質問してみます。
これは何でしょうか? 説明してみてください。
(1) srand
(2) time(NULL)
(3) rand()
(4) %1000
です。
えっと、、、
(1)srand
は、、、あれ、わかんない(;´Д`)
(2)time(NULL)
モ、、、、わからない(´;ω;`)
(3)rand()
これは、、乱数の呼び出しですか???
(4)
これは1000で割ったときの余りを出す計算ですか??

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#4

投稿記事 by みけCAT » 10年前

☆をつけた関数の説明文は苦Cからの引用です。

srand( (unsigned int)time(NULL) );
☆srand : 乱数系列の初期値を与える。
☆time : 現在の時刻を基準時刻からの経過秒数で返す。

乱数系列を現在の時刻に指定するので、(1秒以上間隔をあけて起動すれば)毎回違う乱数が出るようになることを想定しています。

rand()%1000 + 1
☆rand : 乱数を得る。
乱数の値を1000で割ったあまりに1を足しているので、RAND_MAXが十分大きければ[1,1000]の整数の乱数が得られるはずです。
ただし、処理系によっては単純に余りを取ると乱数の精度が悪いかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#5

投稿記事 by Sera » 10年前

みけCAT さんが書きました:☆をつけた関数の説明文は苦Cからの引用です。

srand( (unsigned int)time(NULL) );
☆srand : 乱数系列の初期値を与える。
☆time : 現在の時刻を基準時刻からの経過秒数で返す。

乱数系列を現在の時刻に指定するので、(1秒以上間隔をあけて起動すれば)毎回違う乱数が出るようになることを想定しています。

rand()%1000 + 1
☆rand : 乱数を得る。
乱数の値を1000で割ったあまりに1を足しているので、RAND_MAXが十分大きければ[1,1000]の整数の乱数が得られるはずです。
ただし、処理系によっては単純に余りを取ると乱数の精度が悪いかもしれません。
ムムム、、、
srandとtimeについてはなんとなくは理解できたかも(;^ω^)
でも、unsigned intとNULLの意味がイマイチ、、、

randについては、訳がわかりません(´;ω;`)
1000で割って余りに1を足すと1~999の値になるんですかね。。?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 乱数について

#6

投稿記事 by softya(ソフト屋) » 10年前

googleさんで検索してみましたか? 便利ですよgoogleさん。

とりあえず、C言語の標準ライブラリが説明されているサイトを紹介しておきます。
「ライブラリ関数一覧」
http://www9.plala.or.jp/sgwr-t/lib/libtop.html
(3) 確かにそうですが、もう少し正確にお願いします。
(4) ご自分でも書いてますが割った余りを出します。1000で割ったあまりの値の範囲を書いてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#7

投稿記事 by みけCAT » 10年前

unsigned int : 符号なし整数型
NULL : どこも指していないポインタ
Sera さんが書きました:1000で割って余りに1を足すと1~999の値になるんですかね。。?
少なくとも、「一般的な」割り算と足し算の定義では1~999の値だけにはなりません。
乱数の質が悪ければなるかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#8

投稿記事 by みけCAT » 10年前

自分が前に書いたsrand((unsigned int)time(NULL));の説明です。
N次元の半径1の体積を求める c++ • C言語交流フォーラム ~ mixC++ ~
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#9

投稿記事 by Sera » 10年前

softya(ソフト屋) さんが書きました:googleさんで検索してみましたか? 便利ですよgoogleさん。

とりあえず、C言語の標準ライブラリが説明されているサイトを紹介しておきます。
「ライブラリ関数一覧」
http://www9.plala.or.jp/sgwr-t/lib/libtop.html
(3) 確かにそうですが、もう少し正確にお願いします。
(4) ご自分でも書いてますが割った余りを出します。1000で割ったあまりの値の範囲を書いてみてください。
googleさんで見てみました!(`・ω・´)
srandはコンピュータ内で決まっている乱数の発生系列を変更させるってことですね!

time(NULL)はやっぱり理解できませぬ。。。

(3)は
コンピュータ内のある発生系列に従って文字を渡すってことでしょうか。
(4)は、、、
余りの値の範囲は割ったかず以下だから、、、999ですね!

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#10

投稿記事 by Sera » 10年前

みけCAT さんが書きました:unsigned int : 符号なし整数型
NULL : どこも指していないポインタ
Sera さんが書きました:1000で割って余りに1を足すと1~999の値になるんですかね。。?
少なくとも、「一般的な」割り算と足し算の定義では1~999の値だけにはなりません。
乱数の質が悪ければなるかもしれません。
符号なし整数型っていうのは要するに正数ってことでいいんでしょうか??

どこも指していないポインタというのはどいういった意味なんでしょうか。。。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#11

投稿記事 by みけCAT » 10年前

Sera さんが書きました:time(NULL)はやっぱり理解できませぬ。。。
この値だけを出力してみるといいかもしれません。

コード:

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

int main(void) {
    printf("%u\n",(unsigned int)time(NULL));
    return 0;
}
Sera さんが書きました:符号なし整数型っていうのは要するに正数ってことでいいんでしょうか??
非負整数ですね。
32ビットなら、0以上4294967295以下の整数を表現できます。
Sera さんが書きました:どこも指していないポインタというのはどいういった意味なんでしょうか。。。
「無効」を表現しているポインタです。
今回の場合、時刻を変数に格納せず、戻り値だけ返せばいい、という意味です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 乱数について

#12

投稿記事 by softya(ソフト屋) » 10年前

>(3)は
>コンピュータ内のある発生系列に従って文字を渡すってことでしょうか。

文字は出てきませんよ。数値です。
C言語では数値と文字と文字列の扱いに注意して下さい。

>(4)は、、、
>余りの値の範囲は割ったかず以下だから、、、999ですね!

範囲ですので始まりもお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#13

投稿記事 by みけCAT » 10年前

Sera さんが書きました:(4)は、、、
余りの値の範囲は割ったかず以下だから、、、999ですね!
間違っている気がします。
割ったかず「以下」ではないのではないですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#14

投稿記事 by Sera » 10年前

みけCAT さんが書きました:
Sera さんが書きました:(4)は、、、
余りの値の範囲は割ったかず以下だから、、、999ですね!
間違っている気がします。
割ったかず「以下」ではないのではないですか?
割ったかずより下ですね!笑

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#15

投稿記事 by Sera » 10年前

softya(ソフト屋) さんが書きました:>(3)は
>コンピュータ内のある発生系列に従って文字を渡すってことでしょうか。

文字は出てきませんよ。数値です。
C言語では数値と文字と文字列の扱いに注意して下さい。

>(4)は、、、
>余りの値の範囲は割ったかず以下だから、、、999ですね!

範囲ですので始まりもお願いします。
始まりは、、、
+1しているから1~999でしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#16

投稿記事 by みけCAT » 10年前

Sera さんが書きました:始まりは、、、
+1しているから1~999でしょうか?
違いますね。(範囲は1~999ではないです)
何に+1しましたか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#17

投稿記事 by Sera » 10年前

みけCAT さんが書きました:
Sera さんが書きました:始まりは、、、
+1しているから1~999でしょうか?
違いますね。(範囲は1~999ではないです)
何に+1しましたか?
rand()%1000 + 1
だから、、、余りに+1ですか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#18

投稿記事 by みけCAT » 10年前

Sera さんが書きました:rand()%1000 + 1
だから、、、余りに+1ですか?
はい。
では、+1する前の余りの範囲はどうなりますか?
オフトピック
割られる数が負だと厄介ですが、C言語標準ライブラリのrandの戻り値は0以上のはずなので、ここでは無視します。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#19

投稿記事 by Sera » 10年前

みけCAT さんが書きました:
Sera さんが書きました:rand()%1000 + 1
だから、、、余りに+1ですか?
はい。
では、+1する前の余りの範囲はどうなりますか?
+1しないので0からの範囲ではないでしょうか

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 乱数について

#20

投稿記事 by みけCAT » 10年前

Sera さんが書きました:+1しないので0からの範囲ではないでしょうか
Yes, 0以上999以下ですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

初級者
記事: 200
登録日時: 13年前

Re: 乱数について

#21

投稿記事 by 初級者 » 10年前

1〜1000の数がほしいけど、
rand()が返すのは0以上だしなぁ。

てなときは、こんな風に考える。

1〜1000を無理やり0始まりに変えてしまう。
そうすると、0〜999になる。
0〜999はrand()が返す値を1000で割った
あまりとして得られる。
後は、もともと1から始めたかったので、
1を足す。

結果:
1〜1000をrand()で得るには、
rand() % 1000 + 1

Sera
記事: 31
登録日時: 10年前

Re: 乱数について

#22

投稿記事 by Sera » 10年前

初級者 さんが書きました:1〜1000の数がほしいけど、
rand()が返すのは0以上だしなぁ。

てなときは、こんな風に考える。

1〜1000を無理やり0始まりに変えてしまう。
そうすると、0〜999になる。
0〜999はrand()が返す値を1000で割った
あまりとして得られる。
後は、もともと1から始めたかったので、
1を足す。

結果:
1〜1000をrand()で得るには、
rand() % 1000 + 1
では1~999は
rand() % 999 + 1
ということですね!

閉鎖

“C言語何でも質問掲示板” へ戻る