1------------------------------------------------------------------------------ 2-- -- 3-- GNAT RUN-TIME COMPONENTS -- 4-- -- 5-- G N A T . M B B S _ D I S C R E T E _ R A N D O M -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1992-2010, Free Software Foundation, Inc. -- 10-- -- 11-- This specification is derived from the Ada Reference Manual for use with -- 12-- GNAT. The copyright notice above, and the license provisions that follow -- 13-- apply solely to the contents of the part following the private keyword. -- 14-- -- 15-- GNAT is free software; you can redistribute it and/or modify it under -- 16-- terms of the GNU General Public License as published by the Free Soft- -- 17-- ware Foundation; either version 3, or (at your option) any later ver- -- 18-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 19-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 20-- or FITNESS FOR A PARTICULAR PURPOSE. -- 21-- -- 22-- As a special exception under Section 7 of GPL version 3, you are granted -- 23-- additional permissions described in the GCC Runtime Library Exception, -- 24-- version 3.1, as published by the Free Software Foundation. -- 25-- -- 26-- You should have received a copy of the GNU General Public License and -- 27-- a copy of the GCC Runtime Library Exception along with this program; -- 28-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 29-- <http://www.gnu.org/licenses/>. -- 30-- -- 31-- GNAT was originally developed by the GNAT team at New York University. -- 32-- Extensive contributions were provided by Ada Core Technologies Inc. -- 33-- -- 34------------------------------------------------------------------------------ 35 36-- The implementation used in this package was contributed by Robert 37-- Eachus. It is based on the work of L. Blum, M. Blum, and M. Shub, SIAM 38-- Journal of Computing, Vol 15. No 2, May 1986. The particular choices for P 39-- and Q chosen here guarantee a period of 562,085,314,430,582 (about 2**49), 40-- and the generated sequence has excellent randomness properties. For further 41-- details, see the paper "Fast Generation of Trustworthy Random Numbers", by 42-- Robert Eachus, which describes both the algorithm and the efficient 43-- implementation approach used here. 44 45-- Formerly, this package was Ada.Numerics.Discrete_Random. It is retained 46-- here in part to allow users to reconstruct number sequences generated 47-- by previous versions. 48 49with Interfaces; 50 51generic 52 type Result_Subtype is (<>); 53 54package GNAT.MBBS_Discrete_Random is 55 56 -- The algorithm used here is reliable from a required statistical point of 57 -- view only up to 48 bits. We try to behave reasonably in the case of 58 -- larger types, but we can't guarantee the required properties. So 59 -- generate a warning for these (slightly) dubious cases. 60 61 pragma Compile_Time_Warning 62 (Result_Subtype'Size > 48, 63 "statistical properties not guaranteed for size > 48"); 64 65 -- Basic facilities 66 67 type Generator is limited private; 68 69 function Random (Gen : Generator) return Result_Subtype; 70 71 procedure Reset (Gen : Generator); 72 procedure Reset (Gen : Generator; Initiator : Integer); 73 74 -- Advanced facilities 75 76 type State is private; 77 78 procedure Save (Gen : Generator; To_State : out State); 79 procedure Reset (Gen : Generator; From_State : State); 80 81 Max_Image_Width : constant := 80; 82 83 function Image (Of_State : State) return String; 84 function Value (Coded_State : String) return State; 85 86private 87 subtype Int is Interfaces.Integer_32; 88 subtype Rst is Result_Subtype; 89 90 -- We prefer to use 14 digits for Flt, but some targets are more limited 91 92 type Flt is digits Positive'Min (14, Long_Long_Float'Digits); 93 94 RstF : constant Flt := Flt (Rst'Pos (Rst'First)); 95 RstL : constant Flt := Flt (Rst'Pos (Rst'Last)); 96 97 Offs : constant Flt := RstF - 0.5; 98 99 K1 : constant := 94_833_359; 100 K1F : constant := 94_833_359.0; 101 K2 : constant := 47_416_679; 102 K2F : constant := 47_416_679.0; 103 Scal : constant Flt := (RstL - RstF + 1.0) / (K1F * K2F); 104 105 type State is record 106 X1 : Int := Int (2999 ** 2); 107 X2 : Int := Int (1439 ** 2); 108 P : Int := K1; 109 Q : Int := K2; 110 FP : Flt := K1F; 111 Scl : Flt := Scal; 112 end record; 113 114 type Writable_Access (Self : access Generator) is limited null record; 115 -- Auxiliary type to make Generator a self-referential type 116 117 type Generator is limited record 118 Writable : Writable_Access (Generator'Access); 119 -- This self reference allows functions to modify Generator arguments 120 Gen_State : State; 121 end record; 122 123end GNAT.MBBS_Discrete_Random; 124