MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rand.inc
1 # ==== Purpose ====
2 #
3 # Generate a random number in such a way that the sequence of numbers
4 # generated by successive calls can be deterministic.
5 #
6 # ==== Usage ====
7 #
8 # --let $rand_type= { int | float | decide }
9 # [--let $rand_min= MIN_VALUE]
10 # [--let $rand_max= MAX_VALUE]
11 # [--let $rand_probability= THRESHOLD]
12 # [--let $rand_seed= SEED]
13 # --source include/rand.inc
14 # --echo Random number: $rand
15 #
16 # Parameters:
17 #
18 # $rand_type
19 # If set to 'int', generates an integer in the range
20 # [$rand_min, $rand_max).
21 #
22 # If set to 'float', generates a floating point number in the
23 # range [$rand_min, $rand_max).
24 #
25 # If set to 'decide', generates 1 with probability
26 # $rand_probability and 0 with probability 1-$rand_probability.
27 #
28 # $rand_min, $rand_max
29 # Range of values for $rand_type=int or $rand_type=float.
30 #
31 # $rand_probability
32 # Probability to get a '1' if $rand_type=decide.
33 #
34 # $rand_seed
35 # The seed value. If you want to set the seed to a random number
36 # that is different for each invokation of the test, set
37 # $rand_seed to the empty string. Normally, $rand_seed is only
38 # read in the first invokation of rand.inc. If you want to reset
39 # the seed later, set $_rand_state to the empty string.
40 #
41 # ==== Implementation ====
42 #
43 # This RNG uses the following multiply-with-carry algorithm:
44 # int32 z, w;
45 # if (z == 0) z = 1;
46 # if (w == 0) w = 1;
47 # z = 36969 * (z & 65535) + (z >> 16);
48 # w = 18000 * (w & 65535) + (w >> 16);
49 # rand = (z << 16) + w;
50 # In this implementation, z is stored in the low 32 bits and w in the
51 # high 32 bits of $_rand_state.
52 
53 --let $_maxint32= ((1 << 32) - 1)
54 
55 if ($_rand_state == '')
56 {
57  if ($rand_seed == '')
58  {
59  --let $rand_seed= `SELECT FLOOR(RAND() * (1 << 63))`
60  }
61  --let $write_var= $rand_seed
62  --let $write_to_file= $MYSQLTEST_VARDIR/tmp/rand_seed
63  --source include/write_var_to_file.inc
64  --let $_rand_state= $rand_seed
65  --let $_rand_lo= IF(($_rand_state) & $_maxint32 = 0, 1, ($_rand_state) & $_maxint32)
66  --let $_rand_hi= IF(($_rand_state) >> 32 = 0, 1, ($_rand_state) >> 32)
67  --let $_rand_state= `SELECT ((36969 * $_rand_lo + ($_rand_lo >> 16)) & $_maxint32) + (((18000 * ($_rand_hi & 65535) + ($_rand_hi >> 16)) & $_maxint32) << 32)`
68 }
69 
70 --let $_rand_lo= IF(($_rand_state) & $_maxint32 = 0, 1, ($_rand_state) & $_maxint32)
71 --let $_rand_hi= IF(($_rand_state) >> 32 = 0, 1, ($_rand_state) >> 32)
72 --let $_rand_state= `SELECT ((36969 * $_rand_lo + ($_rand_lo >> 16)) & $_maxint32) + (((18000 * ($_rand_hi & 65535) + ($_rand_hi >> 16)) & $_maxint32) << 32)`
73 --let $rand= ((($_rand_state << 16) + ($_rand_state >> 32)) & $_maxint32)
74 
75 if ($rand_type == decide)
76 {
77  --let $_rand_probability= 0.5
78  if ($rand_probability != '')
79  {
80  --let $_rand_probability= $rand_probability
81  }
82  --let $rand= `SELECT IF($rand / (1 << 32) < ($rand_probability), 1, 0)`
83 }
84 if ($rand_type != decide)
85 {
86  --let $_rand_min= 0
87  if ($rand_min)
88  {
89  --let $_rand_min= $rand_min
90  }
91  --let $_rand_max= 1
92  if ($rand_max)
93  {
94  --let $_rand_max= $rand_max
95  }
96  if ($rand_type == int)
97  {
98  --let $rand= `SELECT ($_rand_min) + ($rand % (($_rand_max) - ($_rand_min)))`
99  }
100  if ($rand_type == float)
101  {
102  --let $rand= `SELECT ($_rand_min) + ($rand * (($_rand_max) - ($_rand_min)) / (1 << 32))`
103  }
104 }