Random real numbers

Back to Random integers. Forward to Other random results. Up to Contents.

The Random class generates two classes of uniform real results: fixed point numbers (where the spacing between possible results is a constant) and floating point numbers (where the spacing between possible results varies).

Fixed-point real numbers

The results returned by Fixed(), FixedU(), FixedN(), FixedW(), FixedO(), and FixedC() are "fixed-point reals" with precision p. These are of the form i / 2p where i is an integer. If, for real data type RealType, we restrict p > 0 and p <= std::numeric_limits<RealType>::digits, then all such numbers in [-1,1] are representable. For p = 3, the set of numbers in [0,1] is {0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1}.

The results returned FixedS() are of "offset fixed-point reals" with precision p. These are of the form (i + 1/2) / 2p where i is an integer. If, for real data type RealType, we restrict p > 0 and p <= std::numeric_limits<RealType>::digits, then all such numbers in (-1/2,1/2) are representable. (This only "works" for radix 2 systems; with larger bases, the results can't be represented exactly.) Note that possibly "exceptional" numbers, -1/2, 0, and 1/2, are not included in this set. For p = 3, the set of numbers in (-1/2,1/2) is {-7/16, -5/16, -3/16, -1/16, 1/16, 3/16, 5/16, 7/16}.

Floating-point real numbers

The results returned by Float(), FloatU(), FloatN(), FloatW() are "floating-point reals" with precision p and exponent range e. The possible results for such floating numbers in [-1,1] consist of

For real data type RealType, such numbers are representable if

For e = 0, the numbers become the fixed point numbers with precision p.

Here is an example of the floating point points with p = 3 and e = 2 together with the probabilities yielded by Float(), FloatU(), FloatN().

Floats with p = 3, e = 2

X

prob(Float() = X)

prob(FloatU() = X)

prob(FloatN() = X)

0

1/32

0

0.5/32

1/32

1/32

1/32

1/32

2/32

1/32

1/32

1/32

3/32

1/32

1/32

1/32

4/32

1/32

1/32

1/32

5/32

1/32

1/32

1/32

6/32

1/32

1/32

1/32

7/32

1/32

1/32

1/32

4/16

1/16

1/32

1.5/32

5/16

1/16

1/16

1/16

6/16

1/16

1/16

1/16

7/16

1/16

1/16

1/16

4/8

1/8

1/16

1.5/16

5/8

1/8

1/8

1/8

6/8

1/8

1/8

1/8

7/8

1/8

1/8

1/8

1

0

1/8

0.5/8

The description of floating-point numbers assumes that the underlying hardware supports denormalized numbers. This is the case with most modern computers. The code attempts to deal also with older hardware where there's a gap between 0 and 1/2e + 1, but this has not been tested.

Summary of real number routines

The following table provides a succinct definition of each of the member functions of Random routines that return a real result. Here u is a uniformly distributed random number in (0,1). This is drawn from a continuous distribution; i.e., it may be thought of as consisting of a binary point followed by an infinite sequence of random binary bits. (This is just a useful conceptual framework. None of the implementations of these functions require an explicit realization of u.)

The term "fixed" means a fixed-point real with precision p, and we have h = 1/2p (the smallest positive fixed-point number). The term "float" means a floating-point real with precision p and exponent range e.

Definitions of routines returning reals

routine

mnemonic

definition

Fixed()

default (down)

round u down to previous fixed

FixedU()

upper

round u up to next fixed

FixedN()

nearest

round u to nearest fixed

FixedW()

wide

round 2u - 1 to nearest fixed

FixedS()

symmetric

round u - 1/2 to nearest offset fixed

FixedO()

open

round (1 - h)u up to nearest fixed

FixedC()

closed

round (1 + h)u down to nearest fixed

Float()

default (down)

round u down to previous float

FloatU()

upper

round u up to next float

FloatN()

nearest

round u to nearest float

FloatW()

wide

round 2u - 1 to nearest float

The precision and exponent range are determined as follows. Each of the fixed-point routines comes in 3 variants, for example,

Similarly each of the floating-point routines comes in 3 variants, for example,

Typical values of digits and min_exponent are given by

Typical parameters for real types

type

digits

-min_exponent

float

24

125

double

53

1021

long double

64

16381

long double (Power PC)

106

968

long double (Sun)

113

16494

In the following tables, the columns have the following meanings

next(X) is the next representable float following X. prev(X) is the previous representable float preceding X.

Properties of routines returning reals

routine

min

max

num

prob

Fixed()

0

1-h

2p

h

FixedU()

h

1

2p

h

FixedN()

0

1

2p + 1

h (h/2 at endpoints)

FixedW()

-1

1

2p+1 + 1

h/2 (h/4 at endpoints)

FixedS()

-(1-h)/2

(1-h)/2

2p

h

FixedO()

h

1-h

2p-1

h/(1-h)

FixedC()

0

1

2p+1

h/(1+h)

Float()

0

1-h

2p(1+e/2)

min(1,next(X))-X

FloatU()

1/2p+e

1

2p(1+e/2)

X-max(0,prev(X))

FloatN()

0

1

2p(1+e/2)+1

(min(1,next(X))-max(0,prev(X)))/2

FloatW()

-1

1

2p+1(1+e/2)+1

(min(1,next(X))-max(-1,prev(X)))/4

From these definitions, we can show that:

We can easily show that certain distributions are equivalent:

Equivalences between routines returning reals

Function

Equivalent

FixedU<RealType,p>()

Fixed<RealType,p>() + h

FixedU<RealType,p>()

1 - Fixed<RealType,p>()

FixedN<RealType,p>()

Boolean() ? Fixed<RealType,p>() : FixedU<RealType,p>()

FixedN<RealType,p>()

1 - FixedN<RealType,p>()

FixedO<RealType,p>()

1 - FixedO<RealType,p>()

FixedC<RealType,p>()

1 - FixedC<RealType,p>()

FixedS<RealType,p>()

Fixed<RealType,p>() - (1-h)/2

FixedS<RealType,p>()

- FixedS<RealType,p>()

FixedW<RealType,p>()

(Boolean() ? 1 : -1) FixedN<RealType,p>()

FixedW<RealType,p>()

- FixedW<RealType,p>()

FixedW<RealType,p-1>()

2 FixedN<RealType,p>() - 1

FloatN<RealType,p,e>()

Boolean() ? Float<RealType,p,e>() : FloatU<RealType,p,e>()

FloatW<RealType,p,e>()

(Boolean() ? 1 : -1) FloatN<RealType,p,e>()

FloatW<RealType,p,e>()

- FloatW<RealType,p,e>()

Float<RealType,p,0>()

Fixed<RealType,p>()

FloatU<RealType,p,0>()

FixedU<RealType,p>()

FloatN<RealType,p,0>()

FixedN<RealType,p>()

FloatW<RealType,p,0>()

FixedW<RealType,p>()

A caution about FixedO() and FixedC(). All four of FixedS(), FixedN() - 0.5, FixedO() - 0.5, and FixedC() - 0.5 produce results which are strictly symmetric about 0 and would thus be suitable for an unbiased random walk. The variances of the first two distributions are 1/12 + O(h2), close to the ideal value. On the other hand the variances of the distributions of FixedO() and FixedC() are 1/12 + O(h), significantly further from the ideal value. (In practice, using a strictly symmetric normal distribution is preferable for simulating a random walk.)

Similarly, consider estimating the value of pi by randomly selecting points in a unit square and determining what fraction lie in a circle of diameter 1. Sampling in the square using FixedO() or FixedC() gives poorer results than FixedN(), and FixedS() gives slightly better results.

Because of their definitions in terms of u, any of Fixed(), FixedU(), FixedN(), or FixedS() can be used to cover the periodic unit interval in an unbiased way. Thus to sample an angle uniformly, use 2.0 * M_PI * Fixed() or 2.0 * M_PI * FixedS(). The latter has the advantage that it is strictly symmetric about zero. In addition, angles which are multiples of pi/2 are avoided (which may obviate the need to check for special cases).

Usually, these real routines would be invoked by specifying the type and allowing the precision to be determined from the type, e.g., Real<double>(). However, in some cases it might be useful to specify a lower precision:

Back to Random integers. Forward to Other random results. Up to Contents.

Generated on Thu Dec 31 15:24:29 2009 by  doxygen 1.6.1