diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-06-22 19:17:57 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2010-06-22 19:17:57 +0200 |
commit | 545cb5be91f8dcaef5b5d27977e47970773d4cca (patch) | |
tree | 6078bcaac066b9b80d5acf54d2737daa1f56b9ed /gcc/ada/s-rannum.adb | |
parent | 879e23f05867aed40198a68fcd3ba8df62ee104c (diff) | |
download | gcc-545cb5be91f8dcaef5b5d27977e47970773d4cca.zip gcc-545cb5be91f8dcaef5b5d27977e47970773d4cca.tar.gz gcc-545cb5be91f8dcaef5b5d27977e47970773d4cca.tar.bz2 |
[multiple changes]
2010-06-22 Robert Dewar <dewar@adacore.com>
* freeze.adb: Minor reformatting
Minor code reorganization (use Nkind_In and Ekind_In).
2010-06-22 Bob Duff <duff@adacore.com>
* gnat1drv.adb (Gnat1drv): Remove the messages that recommend using
-gnatc when a file is compiled that we cannot generate code for, not
helpful and confusing.
2010-06-22 Vincent Celier <celier@adacore.com>
* switch-m.adb (Normalize_Compiler_Switches): Process correctly
switches -gnatknn.
2010-06-22 Paul Hilfinger <hilfinger@adacore.com>
* s-rannum.adb: Replace constants with commented symbols.
* s-rannum.ads: Explain significance of the initial value of the data
structure.
2010-06-22 Ed Schonberg <schonberg@adacore.com>
* a-ngcoty.adb: Clarify comment.
2010-06-22 Gary Dismukes <dismukes@adacore.com>
* exp_pakd.adb (Expand_Bit_Packed_Element_Set): Return without
expansion for indexing packed arrays with small power-of-2 component
sizes when the target is AAMP.
(Expand_Packed_Element_Reference): Return without expansion for
indexing packed arrays with small power-of-2 component sizes when the
target is AAMP.
2010-06-22 Geert Bosch <bosch@adacore.com>
* exp_ch4.adb (Expand_N_In): Do not substitute a valid check for X in
Float'Range.
2010-06-22 Robert Dewar <dewar@adacore.com>
* g-mbdira.adb, g-mbflra.adb, a-nuflra.adb, a-nudira.adb: Minor comment
updates.
From-SVN: r161213
Diffstat (limited to 'gcc/ada/s-rannum.adb')
-rw-r--r-- | gcc/ada/s-rannum.adb | 126 |
1 files changed, 79 insertions, 47 deletions
diff --git a/gcc/ada/s-rannum.adb b/gcc/ada/s-rannum.adb index 227949d..87408c3 100644 --- a/gcc/ada/s-rannum.adb +++ b/gcc/ada/s-rannum.adb @@ -99,30 +99,71 @@ package body System.Random_Numbers is -- Implementation Note -- ------------------------- - -- The design of this spec is very awkward, as a result of Ada 95 not - -- permitting in-out parameters for function formals (most naturally, + -- The design of this spec is a bit awkward, as a result of Ada 95 not + -- permitting in-out parameters for function formals (most naturally -- Generator values would be passed this way). In pure Ada 95, the only - -- solution is to use the heap and pointers, and, to avoid memory leaks, - -- controlled types. + -- solution would be to add a self-referential component to the generator + -- allowing access to the generator object from inside the function. This + -- would work because the generator is limited, which prevents any copy. - -- This is awfully heavy, so what we do is to use Unrestricted_Access to + -- This is a bit heavy, so what we do is to use Unrestricted_Access to -- get a pointer to the state in the passed Generator. This works because -- Generator is a limited type and will thus always be passed by reference. - Low31_Mask : constant := 2**31-1; - Bit31_Mask : constant := 2**31; - - Matrix_A_X : constant array (State_Val range 0 .. 1) of State_Val := - (0, 16#9908b0df#); - Y2K : constant Calendar.Time := Calendar.Time_Of (Year => 2000, Month => 1, Day => 1, Seconds => 0.0); - -- First Year 2000 day + -- First day of Year 2000 (what is this for???) Image_Numeral_Length : constant := Max_Image_Width / N; subtype Image_String is String (1 .. Max_Image_Width); + ---------------------------- + -- Algorithmic Parameters -- + ---------------------------- + + Lower_Mask : constant := 2**31-1; + Upper_Mask : constant := 2**31; + + Matrix_A : constant array (State_Val range 0 .. 1) of State_Val + := (0, 16#9908b0df#); + -- The twist transformation is represented by a matrix of the form + -- + -- [ 0 I(31) ] + -- [ _a ] + -- + -- where 0 is a 31x31 block of 0s, I(31) is the 31x31 identity matrix and + -- _a is a particular bit row-vector, represented here by a 32-bit integer. + -- If integer x represents a row vector of bits (with x(0), the units bit, + -- last), then + -- x * A = [0 x(31..1)] xor Matrix_A(x(0)). + + U : constant := 11; + S : constant := 7; + B_Mask : constant := 16#9d2c5680#; + T : constant := 15; + C_Mask : constant := 16#efc60000#; + L : constant := 18; + -- The tempering shifts and bit masks, in the order applied + + Seed0 : constant := 5489; + -- Default seed, used to initialize the state vector when Reset not called + + Seed1 : constant := 19650218; + -- Seed used to initialize the state vector when calling Reset with an + -- initialization vector. + + Mult0 : constant := 1812433253; + -- Multiplier for a modified linear congruential generator used to + -- initialize the state vector when calling Reset with a single integer + -- seed. + + Mult1 : constant := 1664525; + Mult2 : constant := 1566083941; + -- Multipliers for two modified linear congruential generators used to + -- initialize the state vector when calling Reset with an initialization + -- vector. + ----------------------- -- Local Subprograms -- ----------------------- @@ -153,40 +194,40 @@ package body System.Random_Numbers is function Random (Gen : Generator) return Unsigned_32 is G : Generator renames Gen'Unrestricted_Access.all; Y : State_Val; - I : Integer; + I : Integer; -- should avoid use of identifier I ??? begin I := G.I; if I < N - M then - Y := (G.S (I) and Bit31_Mask) or (G.S (I + 1) and Low31_Mask); - Y := G.S (I + M) xor Shift_Right (Y, 1) xor Matrix_A_X (Y and 1); + Y := (G.S (I) and Upper_Mask) or (G.S (I + 1) and Lower_Mask); + Y := G.S (I + M) xor Shift_Right (Y, 1) xor Matrix_A (Y and 1); I := I + 1; elsif I < N - 1 then - Y := (G.S (I) and Bit31_Mask) or (G.S (I + 1) and Low31_Mask); + Y := (G.S (I) and Upper_Mask) or (G.S (I + 1) and Lower_Mask); Y := G.S (I + (M - N)) xor Shift_Right (Y, 1) - xor Matrix_A_X (Y and 1); + xor Matrix_A (Y and 1); I := I + 1; elsif I = N - 1 then - Y := (G.S (I) and Bit31_Mask) or (G.S (0) and Low31_Mask); - Y := G.S (M - 1) xor Shift_Right (Y, 1) xor Matrix_A_X (Y and 1); + Y := (G.S (I) and Upper_Mask) or (G.S (0) and Lower_Mask); + Y := G.S (M - 1) xor Shift_Right (Y, 1) xor Matrix_A (Y and 1); I := 0; else - Init (G, 5489); + Init (G, Seed0); return Random (Gen); end if; G.S (G.I) := Y; G.I := I; - Y := Y xor Shift_Right (Y, 11); - Y := Y xor (Shift_Left (Y, 7) and 16#9d2c5680#); - Y := Y xor (Shift_Left (Y, 15) and 16#efc60000#); - Y := Y xor Shift_Right (Y, 18); + Y := Y xor Shift_Right (Y, U); + Y := Y xor (Shift_Left (Y, S) and B_Mask); + Y := Y xor (Shift_Left (Y, T) and C_Mask); + Y := Y xor Shift_Right (Y, L); return Y; end Random; @@ -265,17 +306,10 @@ package body System.Random_Numbers is Mantissa : Unsigned; - X : Real; - -- Scaled mantissa - - R : Unsigned_32; - -- Supply of random bits - - R_Bits : Natural; - -- Number of bits left in R - - K : Bit_Count; - -- Next decrement to exponent + X : Real; -- Scaled mantissa + R : Unsigned_32; -- Supply of random bits + R_Bits : Natural; -- Number of bits left in R + K : Bit_Count; -- Next decrement to exponent begin Mantissa := Random (Gen) / 2**Extra_Bits; @@ -388,7 +422,7 @@ package body System.Random_Numbers is declare -- In the 64-bit case, we have to be careful, since not all 64-bit -- unsigned values are representable in GNAT's root_integer type. - -- Ignore different-size warnings here; since GNAT's handling + -- Ignore different-size warnings here since GNAT's handling -- is correct. pragma Warnings ("Z"); -- better to use msg string! ??? @@ -482,7 +516,7 @@ package body System.Random_Numbers is procedure Reset (Gen : out Generator; Initiator : Integer) is begin - pragma Warnings ("C"); + pragma Warnings (Off, "condition is always *"); -- This is probably an unnecessary precaution against future change, but -- since the test is a static expression, no extra code is involved. @@ -502,14 +536,14 @@ package body System.Random_Numbers is end; end if; - pragma Warnings ("c"); + pragma Warnings (On, "condition is always *"); end Reset; procedure Reset (Gen : out Generator; Initiator : Initialization_Vector) is I, J : Integer; begin - Init (Gen, 19650218); -- please give this constant a name ??? + Init (Gen, Seed1); I := 1; J := 0; @@ -517,8 +551,8 @@ package body System.Random_Numbers is for K in reverse 1 .. Integer'Max (N, Initiator'Length) loop Gen.S (I) := (Gen.S (I) - xor ((Gen.S (I - 1) xor Shift_Right (Gen.S (I - 1), 30)) - * 1664525)) + xor ((Gen.S (I - 1) xor Shift_Right (Gen.S (I - 1), 30)) + * Mult1)) + Initiator (J + Initiator'First) + Unsigned_32 (J); I := I + 1; @@ -538,7 +572,7 @@ package body System.Random_Numbers is for K in reverse 1 .. N - 1 loop Gen.S (I) := (Gen.S (I) xor ((Gen.S (I - 1) - xor Shift_Right (Gen.S (I - 1), 30)) * 1566083941)) + xor Shift_Right (Gen.S (I - 1), 30)) * Mult2)) - Unsigned_32 (I); I := I + 1; @@ -548,7 +582,7 @@ package body System.Random_Numbers is end if; end loop; - Gen.S (0) := Bit31_Mask; + Gen.S (0) := Upper_Mask; end Reset; procedure Reset (Gen : out Generator; From_State : Generator) is @@ -612,7 +646,6 @@ package body System.Random_Numbers is begin Result := (others => ' '); - for J in 0 .. N - 1 loop Insert_Image (Result, J, Gen.S ((J + Gen.I) mod N)); end loop; @@ -643,9 +676,8 @@ package body System.Random_Numbers is for I in 1 .. N - 1 loop Gen.S (I) := - 1812433253 - * (Gen.S (I - 1) xor Shift_Right (Gen.S (I - 1), 30)) - + Unsigned_32 (I); + Mult0 * (Gen.S (I - 1) xor Shift_Right (Gen.S (I - 1), 30)) + + Unsigned_32 (I); end loop; Gen.I := 0; |