Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /** | |||
2 | * @file tinymt32.c | |||
3 | * | |||
4 | * @brief Tiny Mersenne Twister only 127 bit internal state | |||
5 | * | |||
6 | * @author Mutsuo Saito (Hiroshima University) | |||
7 | * @author Makoto Matsumoto (The University of Tokyo) | |||
8 | * | |||
9 | * Copyright (C) 2011 Mutsuo Saito, Makoto Matsumoto, | |||
10 | * Hiroshima University and The University of Tokyo. | |||
11 | * All rights reserved. | |||
12 | * | |||
13 | * The 3-clause BSD License is applied to this software, see | |||
14 | * LICENSE.txt | |||
15 | */ | |||
16 | #include "tinymt32.h" | |||
17 | #define MIN_LOOP 8 | |||
18 | #define PRE_LOOP 8 | |||
19 | ||||
20 | /** | |||
21 | * This function represents a function used in the initialization | |||
22 | * by init_by_array | |||
23 | * @param x 32-bit integer | |||
24 | * @return 32-bit integer | |||
25 | */ | |||
26 | ✗ | static uint32_t ini_func1(uint32_t x) { | ||
27 | ✗ | return (x ^ (x >> 27)) * UINT32_C(1664525); | ||
28 | } | |||
29 | ||||
30 | /** | |||
31 | * This function represents a function used in the initialization | |||
32 | * by init_by_array | |||
33 | * @param x 32-bit integer | |||
34 | * @return 32-bit integer | |||
35 | */ | |||
36 | ✗ | static uint32_t ini_func2(uint32_t x) { | ||
37 | ✗ | return (x ^ (x >> 27)) * UINT32_C(1566083941); | ||
38 | } | |||
39 | ||||
40 | /** | |||
41 | * This function certificate the period of 2^127-1. | |||
42 | * @param random tinymt state vector. | |||
43 | */ | |||
44 | 2248 | static void period_certification(tinymt32_t * random) { | ||
45 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2248 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2248 times.
|
2248 | if ((random->status[0] & TINYMT32_MASK) == 0 && |
46 | ✗ | random->status[1] == 0 && | ||
47 | ✗ | random->status[2] == 0 && | ||
48 | ✗ | random->status[3] == 0) { | ||
49 | ✗ | random->status[0] = 'T'; | ||
50 | ✗ | random->status[1] = 'I'; | ||
51 | ✗ | random->status[2] = 'N'; | ||
52 | ✗ | random->status[3] = 'Y'; | ||
53 | } | |||
54 | 2248 | } | ||
55 | ||||
56 | /** | |||
57 | * This function initializes the internal state array with a 32-bit | |||
58 | * unsigned integer seed. | |||
59 | * @param random tinymt state vector. | |||
60 | * @param seed a 32-bit unsigned integer used as a seed. | |||
61 | */ | |||
62 | 2248 | void tinymt32_init(tinymt32_t * random, uint32_t seed) { | ||
63 | 2248 | random->status[0] = seed; | ||
64 | 2248 | random->status[1] = random->mat1; | ||
65 | 2248 | random->status[2] = random->mat2; | ||
66 | 2248 | random->status[3] = random->tmat; | ||
67 |
2/2✓ Branch 0 taken 15736 times.
✓ Branch 1 taken 2248 times.
|
2/2✓ Decision 'true' taken 15736 times.
✓ Decision 'false' taken 2248 times.
|
17984 | for (unsigned int i = 1; i < MIN_LOOP; i++) { |
68 | 15736 | random->status[i & 3] ^= i + UINT32_C(1812433253) | ||
69 | 15736 | * (random->status[(i - 1) & 3] | ||
70 | 15736 | ^ (random->status[(i - 1) & 3] >> 30)); | ||
71 | } | |||
72 | 2248 | period_certification(random); | ||
73 |
2/2✓ Branch 0 taken 17984 times.
✓ Branch 1 taken 2248 times.
|
2/2✓ Decision 'true' taken 17984 times.
✓ Decision 'false' taken 2248 times.
|
20232 | for (unsigned int i = 0; i < PRE_LOOP; i++) { |
74 | 17984 | tinymt32_next_state(random); | ||
75 | } | |||
76 | 2248 | } | ||
77 | ||||
78 | /** | |||
79 | * This function initializes the internal state array, | |||
80 | * with an array of 32-bit unsigned integers used as seeds | |||
81 | * @param random tinymt state vector. | |||
82 | * @param init_key the array of 32-bit integers, used as a seed. | |||
83 | * @param key_length the length of init_key. | |||
84 | */ | |||
85 | ✗ | void tinymt32_init_by_array(tinymt32_t * random, uint32_t init_key[], | ||
86 | int key_length) { | |||
87 | ✗ | const unsigned int lag = 1; | ||
88 | ✗ | const unsigned int mid = 1; | ||
89 | ✗ | const unsigned int size = 4; | ||
90 | unsigned int i, j; | |||
91 | unsigned int count; | |||
92 | uint32_t r; | |||
93 | ✗ | uint32_t * st = &random->status[0]; | ||
94 | ||||
95 | ✗ | st[0] = 0; | ||
96 | ✗ | st[1] = random->mat1; | ||
97 | ✗ | st[2] = random->mat2; | ||
98 | ✗ | st[3] = random->tmat; | ||
99 | ✗ | if (key_length + 1 > MIN_LOOP) { | ||
100 | ✗ | count = (unsigned int)key_length + 1; | ||
101 | } else { | |||
102 | ✗ | count = MIN_LOOP; | ||
103 | } | |||
104 | ✗ | r = ini_func1(st[0] ^ st[mid % size] | ||
105 | ✗ | ^ st[(size - 1) % size]); | ||
106 | ✗ | st[mid % size] += r; | ||
107 | ✗ | r += (unsigned int)key_length; | ||
108 | ✗ | st[(mid + lag) % size] += r; | ||
109 | ✗ | st[0] = r; | ||
110 | ✗ | count--; | ||
111 | ✗ | for (i = 1, j = 0; (j < count) && (j < (unsigned int)key_length); j++) { | ||
112 | ✗ | r = ini_func1(st[i % size] | ||
113 | ✗ | ^ st[(i + mid) % size] | ||
114 | ✗ | ^ st[(i + size - 1) % size]); | ||
115 | ✗ | st[(i + mid) % size] += r; | ||
116 | ✗ | r += init_key[j] + i; | ||
117 | ✗ | st[(i + mid + lag) % size] += r; | ||
118 | ✗ | st[i % size] = r; | ||
119 | ✗ | i = (i + 1) % size; | ||
120 | } | |||
121 | ✗ | for (; j < count; j++) { | ||
122 | ✗ | r = ini_func1(st[i % size] | ||
123 | ✗ | ^ st[(i + mid) % size] | ||
124 | ✗ | ^ st[(i + size - 1) % size]); | ||
125 | ✗ | st[(i + mid) % size] += r; | ||
126 | ✗ | r += i; | ||
127 | ✗ | st[(i + mid + lag) % size] += r; | ||
128 | ✗ | st[i % size] = r; | ||
129 | ✗ | i = (i + 1) % size; | ||
130 | } | |||
131 | ✗ | for (j = 0; j < size; j++) { | ||
132 | ✗ | r = ini_func2(st[i % size] | ||
133 | ✗ | + st[(i + mid) % size] | ||
134 | ✗ | + st[(i + size - 1) % size]); | ||
135 | ✗ | st[(i + mid) % size] ^= r; | ||
136 | ✗ | r -= i; | ||
137 | ✗ | st[(i + mid + lag) % size] ^= r; | ||
138 | ✗ | st[i % size] = r; | ||
139 | ✗ | i = (i + 1) % size; | ||
140 | } | |||
141 | ✗ | period_certification(random); | ||
142 | ✗ | for (i = 0; i < PRE_LOOP; i++) { | ||
143 | ✗ | tinymt32_next_state(random); | ||
144 | } | |||
145 | ✗ | } | ||
146 |