5

これはおそらくばかげた質問ですが、私はこの概念に本当に苦労しています。配列とrand()関数について説明するチュートリアルを行っています。私には2つの問題があります。

1つ目は、明らかに1つのサイコロをシミュレートするために、1〜6の数字をランダムに生成する必要があることです。本はこれを示唆しています:

int       RollOne( void ) {
    return (rand() % 6) + 1;
}

そうですね、rand()は0から32767までの任意の数を生成できます。次に、この数値を6で割った余りを求め、1を加算します。たとえば、3245はランダムに生成されます。それを6で割り、540.8333を与え、余りを取ります。8.333(私が信じる8に切り捨てられます)そして1を追加します。私が怒っていない限り、それは1から6の間ではない9になります。ただし、プログラムは正常に実行され、そのコードを使用して1〜6の数値を取得する方法がわかりません。どんな助けでも大歓迎です。

私が抱えている2番目の問題は、それほど大きな問題ではありませんが、関連性があります。この本は、このコードの意味を省略しています。

srand( clock() );

言及されているのは、srand()がclock()によって提供されるシードを使用して乱数ジェネレーターを初期化することだけです。さて、実際にclock()に何かを入力できますか?もしそうなら、その効果は何ですか?srand(clock())が何をするかについてのちょっとした説明は完璧でしょう。

長い投稿で申し訳ありませんが、壁の「o」テキストを気にしないでください。どんな助けでも本当にありがたいです。

ありがとう、マイク

回答 ありがとうございました:私は自分が何をしていたかを理解しています。皆さんが示しているように、%演算子は除算せず、最高の倍数とオペランドの違いを見つけるだけです。とった!余りは小数を意味しているような印象を受けました。つまり、7/2 = 3.5の場合、余りは0.5です。書き留めたので、私がどれほど愚かであったかがわかります。私のAレベルの数学が何かを考慮してくれてうれしいです.....
ありがとう!

4

6 に答える 6

8

あなたの例は少し間違っています:

3245をランダムに生成した場合、それを6で割ると540.8333になります(整数演算のため、実際には540になります)。その場合、余りは3245- 6 * 540、つまり5になります。5+ 1は6:Dです。

于 2012-08-02T13:56:01.957 に答える
4

rand(clock())のしくみ

シードは、作業を開始するための単なる数字です。

実際には、コンピューターにはランダムのようなものはありません(ランダム性の錯覚だけです)。すべてがシードを含む複雑な計算/変換です。この場合、システムクロックからの(シード)で始まる番号が必要です。常に変化しており、常にランダムな結果を提供する必要があるためです。

おそらく、システムクロック値が入る場所に任意の値を入れることができます。良いランダム性が発生することを期待しないでください。

繰り返しになりますが、clock()は常に変化する値であるため、通常使用されます。

考えてみれば、システムクロックから同じ値を2回取得することはできません。時間の経過は常にあり、その差は1ミリ秒以下である可能性がありますが、変化が小さい場合でも、1ナノ秒前とは異なる時間です。

于 2012-08-02T13:56:59.147 に答える
4

3245はランダムに生成されます。それを6で割り、540.8333を与え、余りを取ります。

整数の切り捨てと剰余の間で混乱しています。整数演算を使用して3245を6で割ると、余りは5(または0.83333 * 6 = 5)になります。

これを確認する別の方法は540*6 = 3240で、残りは5になります。

于 2012-08-02T14:01:52.093 に答える
1

2番目の質問では、srandを使用して乱数ジェネレーターをシードします。コンピューターは、特殊なハードウェアがないと真の乱数を生成できないため、線形合同法ジェネレーター(多くのC標準ライブラリでデフォルトのアルゴリズムとして使用されます)やメルセンヌツイスターなどの数学関数を使用します。これは非常に予測不可能な一連の数値を生成するため、この数学関数をシードして最初の「ランダム」値を与える必要があります。適切なシード値は、プログラムの実行ごとに異なるものになります。同じプログラムを同じ秒に2回実行しない限り、時間は適切です。シードする必要がある理由は、疑似乱数関数が実際にはランダムではないためです。関数に同じシードを与えると、関数は毎回まったく同じ数列を返します(これは、特定の種類のシミュレーションに役立ちます。ただし、ほとんどの場合、実行ごとに異なるものにする必要があります)。

エクササイズ:

このプログラムを実行します。

#include <stdio.h>
int main() {
    srand(1234);
    for (int i=0; i < 20; i++) 
        printf("%d ", rand());
    printf("\n");
}

数回、何が起こるかを観察してから、1234をtime(NULL)に置き換えて、何が起こるかを観察します。変更されたプログラムを非常に迅速に数回実行するシェルスクリプトを作成し、何が起こるかを観察します。

于 2012-08-02T15:32:04.100 に答える
0

余りはどうして8になるのでしょうか?確かにそれは6がもう一度それに入るということを意味しますか?%も除算関数ではなく、異なるdiv関数です。

于 2012-08-02T13:57:14.630 に答える
0

パーセントは分割されません。余りを与えます('mod'関数)。

于 2012-08-02T13:58:06.023 に答える