1(* Title: Tools/random_word.ML 2 Author: Makarius 3 4Simple generator for pseudo-random numbers, using unboxed word 5arithmetic only. Unprotected concurrency introduces some true 6randomness. 7*) 8 9structure Random :> Random = 10struct 11 12(* random words: 0w0 <= result <= max_word *) 13 14(*minimum length of unboxed words on all supported ML platforms*) 15val _ = Word.wordSize >= 30 16 orelse raise Fail ("Bad platform word size"); 17 18val max_word = 0wx3FFFFFFF; 19val top_bit = 0wx20000000; 20 21(*multiplier according to Borosh and Niederreiter (for modulus = 2^30), 22 see http://random.mat.sbg.ac.at/~charly/server/server.html*) 23val a = 0w777138309; 24fun step x = Word.andb (a * x + 0w1, max_word); 25 26fun change r f = r := f (!r); 27local val rand = (*Unsynchronized.*)ref 0w1 28in fun nextWord () = ((*Unsynchronized.*)change rand step; ! rand) end; 29 30(*NB: higher bits are more random than lower ones*) 31fun nextBool () = Word.andb (nextWord (), top_bit) = 0w0; 32 33 34(* random integers: 0 <= result < k *) 35 36val max_int = Word.toInt max_word; 37 38fun nextInt k = 39 if k <= 0 orelse k > max_int then raise Fail ("next_int: out of range") 40 else if k = max_int then Word.toInt (nextWord ()) 41 else Word.toInt (Word.mod (nextWord (), Word.fromInt k)); 42 43(* random reals: 0.0 <= result < 1.0 *) 44 45val scaling = real max_int + 1.0; 46fun nextReal () = real (Word.toInt (nextWord ())) / scaling; 47 48end; 49