Skip to content

Commit 38b7290

Browse files
committed
#320-fix bug in method Cwg128_64::next()
Fixed. Validated.
1 parent 6ba5233 commit 38b7290

File tree

6 files changed

+181
-61
lines changed

6 files changed

+181
-61
lines changed

c++11/cwg128_64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const Cwg128_64::output_type Cwg128_64::next() noexcept
9999
_internal_state.state.state = ((_internal_state.state.state | 1) * (_internal_state.state.a >> 1)) ^ _internal_state.state.weyl;
100100

101101
// returns the xored - shifted output value
102-
return (_internal_state.state.state ^ (_internal_state.state.a >> 48)).lo;
102+
return _internal_state.state.state ^ (_internal_state.state.a >> 48);
103103
}
104104

105105
//---------------------------------------------------------------------------

c++11/cwg128_64.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ SOFTWARE.
4040

4141

4242
//===========================================================================
43-
/** @brief A 128-/64- bits Collatz-Weyl pseudorandom Generator with a short period (1.18e+21).
43+
/** @brief A 128-/64- bits Collatz-Weyl pseudorandom Generator with a short period (1.84e+19).
4444
*
4545
* Pseudo-random numbers generator - Collatz-Weyl pseudorandom Generator
4646
* dedicated to 128-bits calculations and 64-bits output values with small
47-
* period (min 2^71, i.e. 2.36e+21) but short computation time. All CWG
47+
* period (min 2^64, i.e. 1.84e+19) but short computation time. All CWG
4848
* algorithms offer multi streams features, by simply using different initial
4949
* settings for control value 's' - see below.
5050
*
@@ -59,11 +59,11 @@ SOFTWARE.
5959
* PRNG. 's' must be initally odd. 'a', 'weyl' and initial state 'x' may be
6060
* initialized each with any 64-bits value.
6161
*
62-
* See Cwg64 for a minimum 2^70 (i.e. about 1.18e+21) period CW-Generator
62+
* See Cwg64 for a minimum 2^64 (i.e. about 1.84e+19) period CW-Generator
6363
* with very low computation time, medium period, 64- bits output values and
6464
* very good randomness characteristics.
6565
*
66-
* See Cwg128_64 for a minimum 2^135 (i.e. about 4.36e+40) period CW-generator
66+
* See Cwg128_64 for a minimum 2^128 (i.e. about 6.81e+38) period CW-generator
6767
* with very low computation time, medium period, 128-bits output values and
6868
* very good randomness characteristics.
6969
*
@@ -89,9 +89,9 @@ SOFTWARE.
8989
* +------------------------------------------------------------------------------------------------------------------------------------------------+
9090
* | CppRandLib class | [8] generator name | Memory Usage | Period | time-32bits | time-64 bits | SmallCrush fails | Crush fails | BigCrush fails |
9191
* | ---------------- | ------------------ | ------------ | -------- | ----------- | ------------ | ---------------- | ----------- | -------------- |
92-
* | Cwg64 | CWG64 | 8 x 4-bytes | >= 2^70 | n.a. | n.a. | 0 | 0 | 0 |
93-
* | Cwg128_64 | CWG128_64 | 10 x 4-bytes | >= 2^71 | n.a. | n.a. | 0 | 0 | 0 |
94-
* | Cwg128 | CWG128 | 16 x 4-bytes | >= 2^135 | n.a. | n.a. | 0 | 0 | 0 |
92+
* | Cwg64 | CWG64 | 8 x 4-bytes | >= 2^64 | n.a. | n.a. | 0 | 0 | 0 |
93+
* | Cwg128_64 | CWG128_64 | 10 x 4-bytes | >= 2^64 | n.a. | n.a. | 0 | 0 | 0 |
94+
* | Cwg128 | CWG128 | 16 x 4-bytes | >= 2^128 | n.a. | n.a. | 0 | 0 | 0 |
9595
* +------------------------------------------------------------------------------------------------------------------------------------------------+
9696
*
9797
* * _small crush_ is a small set of simple tests that quickly tests some of
@@ -103,11 +103,11 @@ SOFTWARE.
103103
* * _big crush_ is the ultimate set of difficult tests that any GOOD PRNG
104104
* should definitively pass.
105105
*/
106-
class Cwg128_64 : public BaseCWG<std::uint64_t, utils::UInt128, std::uint64_t, 64>
106+
class Cwg128_64 : public BaseCWG<std::uint64_t, utils::UInt128, utils::UInt128, 128>
107107
{
108108
public:
109109
//--- Wrappers ------------------------------------------------------
110-
using MyBaseClass = BaseCWG<std::uint64_t, utils::UInt128, std::uint64_t, 64>;
110+
using MyBaseClass = BaseCWG<std::uint64_t, utils::UInt128, utils::UInt128, 128>;
111111

112112
using output_type = typename MyBaseClass::output_type;
113113
using state_type = typename MyBaseClass::state_type;

c++20/cwg128_64.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const Cwg128_64::output_type Cwg128_64::next() noexcept
107107
_internal_state.state.state = ((_internal_state.state.state | 1) * (_internal_state.state.a >> 1)) ^ _internal_state.state.weyl;
108108

109109
// returns the xored - shifted output value
110-
return (_internal_state.state.state ^ (_internal_state.state.a >> 48)).lo;
110+
return _internal_state.state.state ^ (_internal_state.state.a >> 48);
111111
}
112112

113113
//---------------------------------------------------------------------------

c++20/cwg128_64.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ SOFTWARE.
4040

4141

4242
//===========================================================================
43-
/** @brief A 128-/64- bits Collatz-Weyl pseudorandom Generator with a short period (1.18e+21).
43+
/** @brief A 128-/64- bits Collatz-Weyl pseudorandom Generator with a short period (1.84e+19).
4444
*
4545
* Pseudo-random numbers generator - Collatz-Weyl pseudorandom Generator
4646
* dedicated to 128-bits calculations and 64-bits output values with small
47-
* period (min 2^71, i.e. 2.36e+21) but short computation time. All CWG
47+
* period (min 2^64, i.e. 1.84e+19) but short computation time. All CWG
4848
* algorithms offer multi streams features, by simply using different initial
4949
* settings for control value 's' - see below.
5050
*
@@ -59,11 +59,11 @@ SOFTWARE.
5959
* PRNG. 's' must be initally odd. 'a', 'weyl' and initial state 'x' may be
6060
* initialized each with any 64-bits value.
6161
*
62-
* See Cwg64 for a minimum 2^70 (i.e. about 1.18e+21) period CW-Generator
62+
* See Cwg64 for a minimum 2^64 (i.e. about 1.84e+19) period CW-Generator
6363
* with very low computation time, medium period, 64- bits output values and
6464
* very good randomness characteristics.
6565
*
66-
* See Cwg128_64 for a minimum 2^135 (i.e. about 4.36e+40) period CW-generator
66+
* See Cwg128_64 for a minimum 2^128 (i.e. about 6.81e+38) period CW-generator
6767
* with very low computation time, medium period, 128-bits output values and
6868
* very good randomness characteristics.
6969
*
@@ -89,9 +89,9 @@ SOFTWARE.
8989
* +------------------------------------------------------------------------------------------------------------------------------------------------+
9090
* | CppRandLib class | [8] generator name | Memory Usage | Period | time-32bits | time-64 bits | SmallCrush fails | Crush fails | BigCrush fails |
9191
* | ---------------- | ------------------ | ------------ | -------- | ----------- | ------------ | ---------------- | ----------- | -------------- |
92-
* | Cwg64 | CWG64 | 8 x 4-bytes | >= 2^70 | n.a. | n.a. | 0 | 0 | 0 |
93-
* | Cwg128_64 | CWG128_64 | 10 x 4-bytes | >= 2^71 | n.a. | n.a. | 0 | 0 | 0 |
94-
* | Cwg128 | CWG128 | 16 x 4-bytes | >= 2^135 | n.a. | n.a. | 0 | 0 | 0 |
92+
* | Cwg64 | CWG64 | 8 x 4-bytes | >= 2^64 | n.a. | n.a. | 0 | 0 | 0 |
93+
* | Cwg128_64 | CWG128_64 | 10 x 4-bytes | >= 2^64 | n.a. | n.a. | 0 | 0 | 0 |
94+
* | Cwg128 | CWG128 | 16 x 4-bytes | >= 2^128 | n.a. | n.a. | 0 | 0 | 0 |
9595
* +------------------------------------------------------------------------------------------------------------------------------------------------+
9696
*
9797
* * _small crush_ is a small set of simple tests that quickly tests some of
@@ -103,11 +103,11 @@ SOFTWARE.
103103
* * _big crush_ is the ultimate set of difficult tests that any GOOD PRNG
104104
* should definitively pass.
105105
*/
106-
class Cwg128_64 : public BaseCWG<std::uint64_t, utils::UInt128, std::uint64_t, 64>
106+
class Cwg128_64 : public BaseCWG<std::uint64_t, utils::UInt128, utils::UInt128, 128>
107107
{
108108
public:
109109
//--- Wrappers ------------------------------------------------------
110-
using MyBaseClass = BaseCWG<std::uint64_t, utils::UInt128, std::uint64_t, 64>;
110+
using MyBaseClass = BaseCWG<std::uint64_t, utils::UInt128, utils::UInt128, 128>;
111111

112112
using output_type = typename MyBaseClass::output_type;
113113
using state_type = typename MyBaseClass::state_type;

gTests-c++11/test_prng_cwg128_64.cpp

Lines changed: 81 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,14 @@ namespace tests_prng
6767
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
6868
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
6969

70-
const std::uint64_t expected[]{ 0xfe58a46deb3255a3, 0xff5247d888e1f6f9, 0xc8edfbc5db97fbd8, 0x1477776d4bcda574, 0x6b67ce70627acf91 };
71-
for (std::uint64_t v : expected)
70+
const utils::UInt128 expected[]{
71+
utils::UInt128(0x46ccf3223a782b85, 0xfe58a46deb3255a3),
72+
utils::UInt128(0x62e7cfb01016a2f1, 0xff5247d888e1f6f9),
73+
utils::UInt128(0x418c6a8911ced7d2, 0xc8edfbc5db97fbd8),
74+
utils::UInt128(0x418253ce692904bb, 0x1477776d4bcda574),
75+
utils::UInt128(0xc87203002bed33bb, 0x6b67ce70627acf91)
76+
};
77+
for (utils::UInt128 v : expected)
7278
EXPECT_EQ(v, cwg128_64.next());
7379

7480
EXPECT_EQ(0xd3a4026896aa2ae1, cwg128_64._internal_state.state.a);
@@ -90,8 +96,14 @@ namespace tests_prng
9096
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
9197
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
9298

93-
const std::uint64_t expected[]{ 0xc53b94975ba3603a, 0x4da619774c2acf70, 0x78f8cdb9d76a8b3b, 0xbb9d5d0194c7b4f, 0x9d5ea8e0805c3da8 };
94-
for (std::uint64_t v : expected)
99+
const utils::UInt128 expected[]{
100+
utils::UInt128(0x2dd4b7e7a6f49803, 0xc53b94975ba3603a),
101+
utils::UInt128(0x6ec42845f0568b05, 0x4da619774c2acf70),
102+
utils::UInt128(0x302b16979fa4f2ab, 0x78f8cdb9d76a8b3b),
103+
utils::UInt128(0x80b331250de1c703, 0x0bb9d5d0194c7b4f),
104+
utils::UInt128(0x6df3d55f219736e5, 0x9d5ea8e0805c3da8)
105+
};
106+
for (utils::UInt128 v : expected)
95107
EXPECT_EQ(v, cwg128_64.next());
96108

97109
EXPECT_EQ(0x686964132f6d73c9, cwg128_64._internal_state.state.a);
@@ -113,8 +125,14 @@ namespace tests_prng
113125
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
114126
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
115127

116-
const std::uint64_t expected[]{ 0x9bd3024c4362c804, 0x48c45b1c35f22412, 0xca3ebfc43e0172d, 0x354149d905250477, 0xb3c1a04b68f90bf5 };
117-
for (std::uint64_t v : expected)
128+
const utils::UInt128 expected[]{
129+
utils::UInt128(0x53b31bfca97ecd70, 0x9bd3024c4362c804),
130+
utils::UInt128(0xe641706dfded0032, 0x48c45b1c35f22412),
131+
utils::UInt128(0x4487bfe23bafaa39, 0x0ca3ebfc43e0172d),
132+
utils::UInt128(0x8f2199ea79411ff3, 0x354149d905250477),
133+
utils::UInt128(0x19969ac656420dca, 0xb3c1a04b68f90bf5)
134+
};
135+
for (utils::UInt128 v : expected)
118136
EXPECT_EQ(v, cwg128_64.next());
119137

120138
EXPECT_EQ(0x6a68bf2307108249, cwg128_64._internal_state.state.a);
@@ -137,8 +155,14 @@ namespace tests_prng
137155
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
138156
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
139157

140-
const std::uint64_t expected[]{ 0x999c0206b0d4d040, 0x1bdd1db256ffa0ed, 0x9759261c1b791502, 0xe456bb324834aa01, 0xbe7e8dc4c69739d };
141-
for (std::uint64_t v : expected)
158+
const utils::UInt128 expected[]{
159+
utils::UInt128(0x799e8d5ecae7aace, 0x999c0206b0d4d040),
160+
utils::UInt128(0x3ca2a3e604a32365, 0x1bdd1db256ffa0ed),
161+
utils::UInt128(0x1f4ac131c828c838, 0x9759261c1b791502),
162+
utils::UInt128(0x9a6bcd198b3aa299, 0xe456bb324834aa01),
163+
utils::UInt128(0x033667bbc9639ab1, 0x0be7e8dc4c69739d)
164+
};
165+
for (utils::UInt128 v : expected)
142166
EXPECT_EQ(v, cwg128_64.next());
143167

144168
EXPECT_EQ(0x77fd0c97cdac6d72, cwg128_64._internal_state.state.a);
@@ -160,8 +184,14 @@ namespace tests_prng
160184
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
161185
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
162186

163-
const std::uint64_t expected[]{ 0x97d3c4b544365f60, 0x4a86605ebe6192eb, 0x5b9f7057972b0545, 0xd5e866042850db7d, 0x98437e88fbb8c1f5 };
164-
for (std::uint64_t v : expected)
187+
const utils::UInt128 expected[]{
188+
utils::UInt128(0x4653e4b7ac5d8590, 0x97d3c4b544365f60),
189+
utils::UInt128(0x81f54ad6919c3429, 0x4a86605ebe6192eb),
190+
utils::UInt128(0x4fedccd889e205a4, 0x5b9f7057972b0545),
191+
utils::UInt128(0x9f7d39e1e2c1a76f, 0xd5e866042850db7d),
192+
utils::UInt128(0x493c0adf7baea455, 0x98437e88fbb8c1f5)
193+
};
194+
for (utils::UInt128 v : expected)
165195
EXPECT_EQ(v, cwg128_64.next());
166196

167197
EXPECT_EQ(0x67ef67a6c4e71c9f, cwg128_64._internal_state.state.a);
@@ -183,8 +213,14 @@ namespace tests_prng
183213
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
184214
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
185215

186-
const std::uint64_t expected[]{ 0x74c316a37df311ec, 0xef317b6dbb8bb2c0, 0x1ede53528e8f1440, 0xadc9d06765afa5ba, 0x6afa7b40ecc40951 };
187-
for (std::uint64_t v : expected)
216+
const utils::UInt128 expected[]{
217+
utils::UInt128(0x5cd41015afddc2d2, 0x74c316a37df311ec),
218+
utils::UInt128(0x02db2872975a0dc2, 0xef317b6dbb8bb2c0),
219+
utils::UInt128(0xe9ae077275c3945f, 0x1ede53528e8f1440),
220+
utils::UInt128(0xfb7e4d1728411ef0, 0xadc9d06765afa5ba),
221+
utils::UInt128(0x29303b5b41b2417d, 0x6afa7b40ecc40951)
222+
};
223+
for (utils::UInt128 v : expected)
188224
EXPECT_EQ(v, cwg128_64.next());
189225

190226
EXPECT_EQ(0x602d6cf9c72ac16b, cwg128_64._internal_state.state.a);
@@ -206,8 +242,14 @@ namespace tests_prng
206242
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
207243
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
208244

209-
const std::uint64_t expected[]{ 0xbd0a3fdebf4785b4, 0xe2653e1169475b6a, 0x462c74dc8286f3a3, 0xda25d5e2da77cc6a, 0xdf58233d77e91d2c };
210-
for (std::uint64_t v : expected)
245+
const utils::UInt128 expected[]{
246+
utils::UInt128(0xf6c724125f857c6d, 0xbd0a3fdebf4785b4),
247+
utils::UInt128(0xe521ce43fe0cdc36, 0xe2653e1169475b6a),
248+
utils::UInt128(0x2e110175df284269, 0x462c74dc8286f3a3),
249+
utils::UInt128(0x3778c4aa3b2a0d46, 0xda25d5e2da77cc6a),
250+
utils::UInt128(0x9c342dd376a3f762, 0xdf58233d77e91d2c)
251+
};
252+
for (utils::UInt128 v : expected)
211253
EXPECT_EQ(v, cwg128_64.next());
212254

213255
EXPECT_EQ(0x468fe250bb8832a8, cwg128_64._internal_state.state.a);
@@ -229,8 +271,14 @@ namespace tests_prng
229271
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
230272
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
231273

232-
const std::uint64_t expected[]{ 0x5d0507d668842c81, 0xd331042444b7ec46, 0xa0e197d6293600d7, 0x72ec7391e58463ed, 0x4b87429035bd3cca };
233-
for (std::uint64_t v : expected)
274+
const utils::UInt128 expected[]{
275+
utils::UInt128(0x3b1a6c785f7bec5e, 0x5d0507d668842c81),
276+
utils::UInt128(0xac48c695ba43de23, 0xd331042444b7ec46),
277+
utils::UInt128(0x8f1264811c610a73, 0xa0e197d6293600d7),
278+
utils::UInt128(0xc691aa49d39aa948, 0x72ec7391e58463ed),
279+
utils::UInt128(0x60d4562e4fdab52a, 0x4b87429035bd3cca)
280+
};
281+
for (utils::UInt128 v : expected)
234282
EXPECT_EQ(v, cwg128_64.next());
235283

236284
EXPECT_EQ(0x864ae3146242bc3e, cwg128_64._internal_state.state.a);
@@ -252,8 +300,14 @@ namespace tests_prng
252300
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
253301
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
254302

255-
const std::uint64_t expected[]{ 0xc528f6001bce6f6c, 0x2074ad4a7283a9ae, 0x25b7e72bb5a6037d, 0x40ca44afd9b64e2c, 0xebe74cd080e7675d };
256-
for (std::uint64_t v : expected)
303+
const utils::UInt128 expected[]{
304+
utils::UInt128(0xea77e6c672a15ed7, 0xc528f6001bce6f6c),
305+
utils::UInt128(0x1630b0d1e130934f, 0x2074ad4a7283a9ae),
306+
utils::UInt128(0x0793d8c735b47196, 0x25b7e72bb5a6037d),
307+
utils::UInt128(0x890a8f609f65cd18, 0x40ca44afd9b64e2c),
308+
utils::UInt128(0xdd6604a0ba2e09b3, 0xebe74cd080e7675d)
309+
};
310+
for (utils::UInt128 v : expected)
257311
EXPECT_EQ(v, cwg128_64.next());
258312

259313
EXPECT_EQ(0xf5a51580680fdb82, cwg128_64._internal_state.state.a);
@@ -275,8 +329,14 @@ namespace tests_prng
275329
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
276330
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
277331

278-
const std::uint64_t expected[]{ 0xec288dd0f1298f2a, 0x4e26f7747cde7909, 0x3137387601cab2ab, 0xa1faef3817023fcf, 0xbfa5bbb9b880621a };
279-
for (std::uint64_t v : expected)
332+
const utils::UInt128 expected[]{
333+
utils::UInt128(0xf5a9f1439499bd9f, 0xec288dd0f1298f2a),
334+
utils::UInt128(0x14be0cf83b066fd0, 0x4e26f7747cde7909),
335+
utils::UInt128(0x90fb5b4080f29a42, 0x3137387601cab2ab),
336+
utils::UInt128(0x75d35c56e5d992a7, 0xa1faef3817023fcf),
337+
utils::UInt128(0xaa642445fb13ed6e, 0xbfa5bbb9b880621a)
338+
};
339+
for (utils::UInt128 v : expected)
280340
EXPECT_EQ(v, cwg128_64.next());
281341

282342
EXPECT_EQ(0xf9f9492a1acd86a4, cwg128_64._internal_state.state.a);
@@ -285,7 +345,7 @@ namespace tests_prng
285345
EXPECT_EQ(0xbfa5bbb9b8809be3, cwg128_64._internal_state.state.state.lo);
286346
EXPECT_EQ(0xd4db17fa8c282951, cwg128_64._internal_state.state.weyl);
287347
EXPECT_FALSE(cwg128_64._internal_state.gauss_valid);
288-
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
348+
EXPECT_DOUBLE_EQ(0.0, cwg128_64._internal_state.gauss_next);
289349
}
290350

291351
EXPECT_THROW(Cwg128_64(-8.87e+18), FloatValueRange01Exception);

0 commit comments

Comments
 (0)