?RCS: $Id: randfunc.U,v 3.0 1993/08/18 12:09:39 ram Exp $ ?RCS: ?RCS: Copyright (c) 1991-1993, Raphael Manfredi ?RCS: ?RCS: You may redistribute only under the terms of the Artistic Licence, ?RCS: as specified in the README file that comes with the distribution. ?RCS: You may reuse parts of this distribution only within the terms of ?RCS: that same Artistic Licence; a copy of which may be found at the root ?RCS: of the source tree for dist 3.0. ?RCS: ?RCS: $Log: randfunc.U,v $ ?RCS: Revision 3.0 1993/08/18 12:09:39 ram ?RCS: Baseline for dist 3.0 netwide release. ?RCS: ?X: ?X: This is the new unit that should be used when random ?X: functions are to be used. It thus makes randbits.U obsolete. ?X: ?X: This unit gives a simple #define for Drand01, which produces ?X: doubles in the range [0,1) using the "best" random number ?X: generator available. The source should just call Drand01 ?X: and not worry about the underlying implementation. ?X: Andy Dougherty July 1998 ?X: ?MAKE:randfunc drand01 seedfunc randbits randseedtype: \ cat rm test i_stdlib i_unistd Compile Myread Csym ccflags ?MAKE: -pick add $@ %< ?S:randfunc: ?S: Indicates the name of the random number function to use. ?S: Values include drand48, random, and rand. In C programs, ?S: the 'Drand01' macro is defined to generate uniformly distributed ?S: random numbers over the range [0., 1.[ (see drand01 and nrand). ?S:. ?S:drand01: ?S: Indicates the macro to be used to generate normalized ?S: random numbers. Uses randfunc, often divided by ?S: (double) (((unsigned long) 1 << randbits)) in order to ?S: normalize the result. ?S: In C programs, the macro 'Drand01' is mapped to drand01. ?S:. ?S:randseedtype: ?S: Indicates the type of the argument of the seedfunc. ?S:. ?S:seedfunc: ?S: Indicates the random number generating seed function. ?S: Values include srand48, srandom, and srand. ?S:. ?S:randbits: ?S: Indicates how many bits are produced by the function used to ?S: generate normalized random numbers. ?S:. ?C:RANDFUNC: ?C: This symbol defines the random function used to define Drand01(). ?C:. ?C:Drand01: ?C: This macro is to be used to generate uniformly distributed ?C: random numbers over the range [0., 1.[. You may have to supply ?C: an 'extern double drand48();' in your program since SunOS 4.1.3 ?C: doesn't provide you with anything relevant in its headers. ?C: See HAS_DRAND48_PROTO. ?C:. ?C:Rand_seed_t: ?C: This symbol defines the type of the argument of the ?C: random seed function. ?C:. ?C:seedDrand01: ?C: This symbol defines the macro to be used in seeding the ?C: random number generator (see Drand01). ?C:. ?C:RANDBITS: ?C: This symbol indicates how many bits are produced by the ?C: function used to generate normalized random numbers. ?C: Values include 15, 16, 31, and 48. ?C:. ?H:#define RANDFUNC $randfunc /**/ ?H:#define Drand01() $drand01 /**/ ?H:#define Rand_seed_t $randseedtype /**/ ?H:#define seedDrand01(x) $seedfunc((Rand_seed_t)x) /**/ ?H:#define RANDBITS $randbits /**/ ?H:. ?T:cont val ?LINT:change ccflags : How can we generate normalized random numbers ? echo " " echo "Looking for a random number function..." >&4 case "$randfunc" in '') if set drand48 val -f; eval $csym; $val; then dflt="drand48" echo "Good, found drand48()." >&4 elif set random val -f; eval $csym; $val; then dflt="random" echo "OK, found random()." >&4 else dflt="rand" echo "Yick, looks like I have to use rand()." >&4 fi echo " " ;; *) dflt="$randfunc" ;; esac cont=true case "$ccflags" in *-Dmy_rand=*|*-Dmy_srand=*) echo "Removing obsolete -Dmy_rand, -Dmy_srand, and -Drandbits from ccflags." >&4 ccflags="`echo $ccflags | sed -e 's/-Dmy_rand=random/ /'`" ccflags="`echo $ccflags | sed -e 's/-Dmy_srand=srandom/ /'`" ccflags="`echo $ccflags | sed -e 's/-Drandbits=[0-9][0-9]*/ /'`" ;; esac while $test "$cont"; do rp="Use which function to generate random numbers?" . ./myread ?X: Invalidate randbits if the answer is not the default so ?X: that the value stored in config.sh will not be used when ?X: we change our random function. if $test "$ans" = "$dflt"; then : null else randbits='' fi randfunc="$ans" if set $ans val -f; eval $csym; $val; then cont='' else dflt=y rp="I cannot find function $ans. Use that name anyway?" . ./myread dflt=rand case "$ans" in [yY]*) cont='';; esac fi case "$cont" in '') case "$randfunc" in drand48) drand01="drand48()" seedfunc="srand48" randbits=48 randseedtype=long ;; rand|random) case "$randbits" in '') echo "Checking to see how many bits your $randfunc() function produces..." >&4 $cat >try.c < #ifdef I_UNISTD # include #endif #ifdef I_STDLIB # include #endif int main() { register int i; register unsigned long tmp; register unsigned long max = 0L; for (i = 1000; i; i--) { tmp = (unsigned long) $randfunc(); if (tmp > max) max = tmp; } for (i = 0; max; i++) max /= 2; printf("%d\n",i); } EOCP set try if eval $compile_ok; then dflt=`try` else dflt='?' echo "(I can't seem to compile the test program...)" fi ;; *) dflt="$randbits" ;; esac rp="How many bits does your $randfunc() function produce?" . ./myread randbits="$ans" $rm -f try.c try drand01="($randfunc() / (double) ((unsigned long)1 << $randbits))" seedfunc="s$randfunc" randseedtype=unsigned ;; ?X: The following is provided just in case... *) dflt="31" rp="How many bits does your $randfunc() function produce?" . ./myread randbits="$ans" seedfunc="s$randfunc" drand01="($randfunc() / (double) ((unsigned long)1 << $randbits))" if set $seedfunc val -f; eval $csym; $val; then echo "(Using $seedfunc() to seed random generator)" else echo "(Warning: no $seedfunc() to seed random generator)" seedfunc=rand fi randseedtype=unsigned ;; esac ;; esac done