Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site allegra.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!don From: don@allegra.UUCP (D. Mitchell) Newsgroups: net.math,net.unix-wizards Subject: Bug fix for 4.2bsd random.c Message-ID: <2425@allegra.UUCP> Date: Wed, 18-Apr-84 18:56:54 EST Article-I.D.: allegra.2425 Posted: Wed Apr 18 18:56:54 1984 Date-Received: Thu, 19-Apr-84 04:18:42 EST Organization: AT&T Bell Laboratories, Murray Hill Lines: 74 1,348c /* * Additive Random Number Generator (see: Knuth 3.2.2) * D. P. Mitchell 84/04/16. */ #define LENGTH 97 #define TAP 12 #define MANTISSA 56 static long y[LENGTH], *tap = &y[0], *feedback = &y[LENGTH - TAP]; static double fy[LENGTH], *ftap = &fy[0], *ffeedback = &fy[LENGTH - TAP]; static unsigned long x = 0xc0393e8d; random() { if (--tap < y) { if (x) /* effect of srandom might be delayed */ setup(); tap += LENGTH; } if (--feedback < y) feedback += LENGTH; return (*feedback += *tap) >> 1 & 0x7fffffff; } double frandom() { double sum; if (--ftap < fy) { if (x) /* fy cannot be preset portably! */ setup(); ftap += LENGTH; } if (--ffeedback < fy) ffeedback += LENGTH; sum = *ftap + *ffeedback; if (sum >= 1.0) { sum = *ftap - 0.5; /* must not overflow! */ sum += *ffeedback - 0.5; } *ffeedback = sum; return sum; } srandom(seed) long seed; { x = seed; } static setup() { long mask; double divisor; int i; for (i = 0; i < LENGTH; i++) { x = 177988*x*x + 505360173*x + 907633385; y[i] = x; } mask = 0x7fffffff >> (63 - MANTISSA); divisor = (double)mask + 1.0; for (i = 0; i < LENGTH; i++) { x = 177988*x*x + 505360173*x + 907633385; fy[i] = (double)x / 4294967296.0; x = 177988*x*x + 505360173*x + 907633385; fy[i] = ((double)(x & mask) + fy[i]) / divisor; } x = 0; } .