aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/s-rannum.adb
diff options
context:
space:
mode:
authorRobert Dewar <dewar@adacore.com>2010-06-22 15:32:18 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2010-06-22 17:32:18 +0200
commit1c612f29199ea74e57bd9872e11ee726703aab2f (patch)
tree6be3a62286a2a9099d500772a40a7709b0eb4b9b /gcc/ada/s-rannum.adb
parent82c2f1bbd38efde4a5891659ee1eeffbbfae56f6 (diff)
downloadgcc-1c612f29199ea74e57bd9872e11ee726703aab2f.zip
gcc-1c612f29199ea74e57bd9872e11ee726703aab2f.tar.gz
gcc-1c612f29199ea74e57bd9872e11ee726703aab2f.tar.bz2
s-rannum.adb, [...]: Minor reformatting.
2010-06-22 Robert Dewar <dewar@adacore.com> * s-rannum.adb, a-nudira.adb, types.ads, freeze.adb, sem_aggr.adb, exp_aggr.adb: Minor reformatting. * gnat_rm.texi: Document GNAT.MBBS_Discrete_Random and GNAT.MBSS_Float_Random. * g-mbdira.adb, g-mbflra.adb, g-mbdira.ads, g-mbflra.ads: Fix header. From-SVN: r161194
Diffstat (limited to 'gcc/ada/s-rannum.adb')
-rw-r--r--gcc/ada/s-rannum.adb51
1 files changed, 26 insertions, 25 deletions
diff --git a/gcc/ada/s-rannum.adb b/gcc/ada/s-rannum.adb
index c161b6e..29a8e94 100644
--- a/gcc/ada/s-rannum.adb
+++ b/gcc/ada/s-rannum.adb
@@ -203,33 +203,32 @@ package body System.Random_Numbers is
function Random_Float_Template (Gen : Generator) return Real is
-- This code generates random floating-point numbers from unsigned
- -- integers. Assuming that Real'Machine_Radix = 2, it can deliver
- -- all machine values of type Real (at least as implied by
- -- Real'Machine_Mantissa and Real'Machine_Emin), which is not true
- -- of the standard method (to which we fall back for non-binary
- -- radix): computing Real(<random integer>) / (<max random integer>+1).
- -- To do so, we first extract an (M-1)-bit significand (where M
- -- is Real'Machine_Mantissa), and then decide on a normalized
- -- exponent by repeated coin flips, decrementing from 0 as long as
- -- we flip heads (1 bits). This yields the proper geometric
- -- distribution for the exponent: in a uniformly distributed set of
- -- floating-point numbers, 1/2 of them will be in [0.5, 1), 1/4 will
- -- be in [0.25, 0.5), and so forth. If the process reaches
- -- Machine_Emin (an extremely rare event), it uses the selected
- -- mantissa bits as an unnormalized fraction with Machine_Emin as
- -- exponent. Otherwise, it adds a leading bit to the selected
- -- mantissa bits (thus giving a normalized fraction) and adjusts by
- -- the chosen exponent. The algorithm attempts to be stingy with
- -- random integers. In the worst case, it can consume roughly
- -- -Real'Machine_Emin/32 32-bit integers, but this case occurs with
- -- probability 2**Machine_Emin, and the expected number of calls to
- -- integer-valued Random is 1.
+ -- integers. Assuming that Real'Machine_Radix = 2, it can deliver all
+ -- machine values of type Real (as implied by Real'Machine_Mantissa and
+ -- Real'Machine_Emin), which is not true of the standard method (to
+ -- which we fall back for non-binary radix): computing Real(<random
+ -- integer>) / (<max random integer>+1). To do so, we first extract an
+ -- (M-1)-bit significand (where M is Real'Machine_Mantissa), and then
+ -- decide on a normalized exponent by repeated coin flips, decrementing
+ -- from 0 as long as we flip heads (1 bits). This yields the proper
+ -- geometric distribution for the exponent: in a uniformly distributed
+ -- set of floating-point numbers, 1/2 of them will be in [0.5, 1), 1/4
+ -- will be in [0.25, 0.5), and so forth. If the process reaches
+ -- Machine_Emin (an extremely rare event), it uses the selected mantissa
+ -- bits as an unnormalized fraction with Machine_Emin as exponent.
+ -- Otherwise, it adds a leading bit to the selected mantissa bits (thus
+ -- giving a normalized fraction) and adjusts by the chosen exponent. The
+ -- algorithm attempts to be stingy with random integers. In the worst
+ -- case, it can consume roughly -Real'Machine_Emin/32 32-bit integers,
+ -- but this case occurs with probability 2**Machine_Emin, and the
+ -- expected number of calls to integer-valued Random is 1.
begin
if Real'Machine_Radix /= 2 then
declare
- Val : constant Real := Real'Machine
- (Real (Unsigned'(Random (Gen))) * 2.0**(-Unsigned'Size));
+ Val : constant Real :=
+ Real'Machine
+ (Real (Unsigned'(Random (Gen))) * 2.0**(-Unsigned'Size));
begin
if Val < 1.0 then
return Real'Base (Val);
@@ -237,20 +236,21 @@ package body System.Random_Numbers is
return Real'Pred (1.0);
end if;
end;
+
else
declare
Mant_Bits : constant Integer := Real'Machine_Mantissa - 1;
Mant_Mask : constant Unsigned := 2**Mant_Bits - 1;
Adjust32 : constant Integer := Real'Size - Unsigned_32'Size;
Leftover : constant Integer :=
- Unsigned'Size - Real'Machine_Mantissa + 1;
-
+ Unsigned'Size - Real'Machine_Mantissa + 1;
V : constant Unsigned := Random (Gen);
Mant : constant Unsigned := V and Mant_Mask;
Rand_Bits : Unsigned_32;
Exp : Integer;
Bits_Left : Integer;
Result : Real;
+
begin
Rand_Bits := Unsigned_32 (Shift_Right (V, Adjust32));
Exp := 0;
@@ -271,6 +271,7 @@ package body System.Random_Numbers is
Rand_Bits := Random (Gen);
end if;
end loop;
+
return Result;
end;
end if;