/*      乱数発生関数 on 1996/12/ 5 by tutimura@kuamp

        my_rand() は、0 と MY_RAND_MAX の間の数字を返します。
        gcc では、MY_RAND_MAX == 65535 です。
        my_srand(seed) は、乱数系列を新たに seed に設定します。

        標準関数の rand(), srand(), RAND_MAX とほぼ同じ働きをします。
        my_rand() に用いている方法は、ANSI お薦めの由緒ある？ものですが、
        最善の乱数発生関数というわけではありません。
        得られる乱数系列を、コンパイラに依存したくない時にお使い下さい。

        [0,N) の乱数を得たい場合は、( my_rand() % N ) とすればいいですが、
        (int)( (double)my_rand() / (MY_RAND_MAX+1) * N ) とする方が、
        はるかに計算時間がかかりますが、より良い乱数が得られるそうです。

        同じ乱数系列を得たくない時には
                #include <time.h>
                main() {
                        my_srand( time(NULL) );
                        ...
                }
        としましょう。
*/

#include <limits.h>

#define MY_RAND_MAX             ( ULONG_MAX / 65536L )
#if UINT_MAX < MY_RAND_MAX
#undef  MY_RAND_MAX
#define MY_RAND_MAX             UINT_MAX
#endif

static unsigned long my_rand_seed = 1;

/* 種を設定 */
void my_srand( unsigned long seed ) {
        my_rand_seed = seed;
}

/* 本体 */
unsigned my_rand( void ) {
        my_rand_seed *= 1103515245UL;
        my_rand_seed += 12345;
        return (unsigned)( my_rand_seed / 65536L );
}

#ifdef TEST
#include <stdio.h>
#include <stdlib.h>

void main() {
        int i;
        printf( "MY_RAND_MAX = %u\t", MY_RAND_MAX );
        printf( "   RAND_MAX = %u\n", RAND_MAX );

        for ( i=0; i<10; i++ ) {
                printf( "%6X - %6X\n", my_rand(), rand() );
        }
}
#endif
