(* Last modified on Thu Jun 21 18:07:44 1990 By piet@cs.ruu.nl *) (* modified on Fri Apr 13 00:56:00 1990 By muller *) (* modified on Fri Mar 9 14:55:13 1990 By uunet!mntgfx!lisch *) UNSAFE MODULE HP300RandomReal EXPORTS Random; IMPORT Word; (* Implements Random.Real and Random.LongReal for IEEE floating-point format, as available on the HP 9000/300 series. *) PROCEDURE Real (self: T := Default): REAL = CONST ExponentBias = 127; (* Exponent bias for REAL *) FractionBits = 23; (* Number of explicit fraction bits *) WordSize = 32; (* Size of INTEGER in bits *) VAR frac, exp: INTEGER; BEGIN (* Generate a random fraction and get its first non-zero word: *) exp := ExponentBias - 1; frac := Integer (self); WHILE (frac = 0) AND (exp >= WordSize) DO (* This loop is (almost) never executed: *) DEC (exp, WordSize); frac := Integer (self); END; (* Normalize: *) WHILE (frac > 0) AND (exp > 0) DO (* This loop is executed about once on the average. *) frac := Word.Shift (frac, 1); DEC (exp); END; IF ((ExponentBias - 1 - exp) MOD WordSize) > WordSize - FractionBits THEN (* Needs more random bits *) frac := Integer (self) END; (* Repack as REAL: *) RETURN LOOPHOLE ( Word.Or ( Word.Shift (exp, FractionBits), Word.Shift ( Word.And (frac, 16_7fffffff), -(WordSize - 1 - FractionBits) ) ), REAL ); END Real; PROCEDURE LongReal (self: T := Default): LONGREAL = CONST ExponentBias = 1023; (* Exponent bias for LONGREAL *) FractionBits = 20; (* Number of fraction bits in high half *) WordSize = 32; (* Size of INTEGER in bits *) VAR frac, exp: INTEGER; dbl: ARRAY [0..1] OF Word.T; BEGIN (* Generate a random fraction and get the first non-zero word: *) exp := ExponentBias - 1; frac := Integer (self); WHILE (frac = 0) AND (exp >= WordSize) DO (* This loop is (almost) never executed: *) DEC (exp, WordSize); frac := Integer (self); END; (* Normalize: *) WHILE (frac > 0) AND (exp > 0) DO (* This loop is executed about once on the average. *) frac := Word.Shift (frac, 1); DEC (exp); END; IF ((ExponentBias - 1 - exp) MOD WordSize) > WordSize - FractionBits THEN (* Needs more random bits *) frac := Integer (self); END; (* Repack as LONGREAL: *) dbl[0] := Integer (self);(* Low-order fraction bits *) dbl[1] := Word.Or ( Word.Shift (exp, FractionBits), Word.Shift (Word.And (frac, 16_7fffffff), -(WordSize - 1 - FractionBits)) ); RETURN LOOPHOLE(dbl, LONGREAL) END LongReal; BEGIN END HP300RandomReal.