C言語関係掲示板

過去ログ

No.557.ユーザ入力のランダム性を利用した擬似乱数

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

rand()関数を用いらない疑似乱数について
投稿者---偽ギルガメッシュ(2003/02/06 12:05:30)



 Cの初心者のくせに、なぜかアセンブラに興味がでたので関係する書物をみていたら、入力の合図があるまで、数字をカウントすることで、乱数もどきを出力するというプログラムがあったので、C言語で表現してみました。
 見苦しい部分もあるかもしれませんが、ご意見ください。

#include <stdio.h>
#include <conio.h>/*ANSI Cではなく、borland cを用いたプログラムなので注意*/

main()

{
 int i,j;           /*rand()関数を用いらない乱数制作法*/
 i = 0;

  while(1)
  {
   j = kbhit();    /*入力は待ってはくれない*/

    if ( !(i % 7)) i= 0; /*7になったら0になる*/

    else if (j) break;   /*0以外の値の時に入力があれば値を返す*/

    i++ ;

   }


  printf("でてきたのは%d",i);

 return i;

 }


 私の考える利点としては、いちいち時計を使う必要がないことぐらいです。
 処理としてはやはり、rand()関数を用いた方がいいのでしょうか・・・。
 もし、ほかにもrand()関数を用いらない疑似乱数を出力するプログラムがありましたら、教えてください。

No.5038

Re:rand()関数を用いらない疑似乱数について
投稿者---stosd(2003/02/06 17:50:48)


意見だけ言わせてください。

この方法は懐かしいですね。ユーザ入力のランダム性を利用したものですね。Z80の頃は擬似乱数として主にゲームで盛んに使われていました。
Z80にはリフレッシュレジスタというものがあり、CPUが自動でインクリメントしているので擬似乱数に使うのにはうってつけでした(もちろん、本来の目的は乱数のためではありませんが)。
(0〜255までの擬似乱数)
#include <stdio.h>
#include <conio.h>

int     main(void)
{
    unsigned char       i;

    for(i = 0;!kbhit();i++);
    getch();

    printf("でてきたのは%d",i);

    return 0;
}

簡単なアプリケーションなら今でも実用的だと思いますよ。乱数を得るだけでなく、srandのシードを作るのにも応用できます(簡単に済ませる時にはtimeの戻り値を使いますよね)。

他には"メモリ中にランダムな数値が並んでる"と見立てて、適当なアドレスから連続して参照する、といった方法もありましたが、現在の32bit環境では難しいですね。
もっと面白いものがあると思いますが、他の回答者の方々に期待いたします。

実際のプログラミングでは、特に別のアルゴリズムを求められているのでなければ"標準関数にあるものはそれを使う"とした方がいいと思います。rand関数を見れば"乱数を使っているな"と一目でわかりますし、デバッグも容易になりますからね。勉強としてなら、アルゴリズムを考える良いトレーニングになると思いますので、ランダム以外のものについても追求することをお勧めします。


>Cの初心者のくせに、なぜかアセンブラに興味がでたので関係する書物をみていたら、入力の合図があるまで、数字をカウントすることで、乱数もどきを出力するというプログラムがあったので、C言語で表現してみました。

アセンブラに興味を持つのは大変良いことだと思いますよ。Cでは山場とされるポインタの理解が容易になりますので、私個人としてはCを始めるまえにアセンブラの習得をお勧めしたいくらいです。Cの勉強がそっちのけにならない程度にアセンブラもかじってみると理解が深まると思いますよ。