Skip to content

Commit a7c2c4e

Browse files
authored
Collatz Generators (#27)
* Create CG128.h * Update rng.c * Update rng.c * Update rng.c * Update rng.c * Create CG64 * Rename CG64 to CG64.h * Update rng.c * Update CG128.h * Update CG64.h * Update CG128.h * Create CG128-64.h * Update CG128-64.h * Update CG128.h * Update CG64.h * Update CG64.h * Update rng.c * Update rng.c * Update CG64.h * Update CG64.h * Update CG64.h * Update CG128-64.h * Update CG128-64.h * Update CG64.h * Update CG128-64.h * Update CG128-64.h * Update CG128-64.h * Create splitmix63.h * Update splitmix63.h * Update CG128-64.h * Update CG64.h * Update splitmix63.h
1 parent d86af75 commit a7c2c4e

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

source/CG128-64.h

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define CG128_64_H
33

44
#include "splitmix64.h"
5+
#include "splitmix63.h"
56
#include <stdint.h>
67

78
/* Written in 2023 by Tomasz R. Dziala ([email protected]).
@@ -38,32 +39,16 @@ void initializator(void)
3839
static uint64_t CG_s, CG_k = 0, CG_weyl = 0;
3940
static __uint128_t CG_x;
4041

41-
// call this to seed CG_x
42+
// call this to seed CG_x and CG_s
4243
static inline void CG128_64_seed(uint64_t seed) {
4344
CG_x = ((__uint128_t)splitmix64_r(&seed) << 64) | (splitmix64_r(&seed) | 1);
45+
CG_s = (splitmix63_r(&seed) << 1) | 1;
4446
}
4547

46-
/* This is Splitmix63, modified Splitmix64 written in 2015 by Sebastiano Vigna. The state of Splitmix63
47-
may be seeded with any value. Outputs of Splitmix63 may be used to to serially seed c[0] states
48-
of Collatz Generator by s = (next_splitmix63() << 1) | 1; */
49-
50-
// call this to seed CG_s
51-
52-
static uint64_t CG64_128_y = 123;
53-
54-
uint64_t CG64_128_next_splitmix63(void) {
55-
uint64_t CG64_128_z = (CG64_128_y += 0x9e3779b97f4a7c15) & 0x7fffffffffffffff;
56-
CG64_128_z = ((CG64_128_z ^ (CG64_128_z >> 30)) * 0xbf58476d1ce4e5b9) & 0x7fffffffffffffff;
57-
CG64_128_z = ((CG64_128_z ^ (CG64_128_z >> 27)) * 0x94d049bb133111eb) & 0x7fffffffffffffff;
58-
return CG64_128_z ^ (CG64_128_z >> 31);
59-
}
60-
61-
CG_s = (CG64_128_next_splitmix63() << 1) | 1;
62-
6348
static inline __uint128_t CG128_64(void)
6449
{
65-
CG_x = (CG_x | 1) * ((CG_k += CG_x) >> 1) ^ (CG_weyl += CG_s);
66-
return CG_k >> 48 ^ CG_x;
50+
CG_x = (CG_x | 1) * ((CG_k += CG_x) >> 1) ^ (CG_weyl += CG_s);
51+
return CG_k >> 48 ^ CG_x;
6752
}
6853

69-
#endif // CG128_64_H
54+
#endif // CG128_64_H

source/CG64.h

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef CG64_H
22
#define CG64_H
33

4-
#include "splitmix64.h"
4+
#include "splitmix63.h"
55
#include <stdint.h>
66

77
/* Written in 2023 by Tomasz R. Dziala ([email protected]).
@@ -37,25 +37,15 @@ void initializator(void)
3737

3838
static uint64_t CG64_c[4];
3939

40-
/* This is Splitmix63, modified Splitmix64 written in 2015 by Sebastiano Vigna. The state of Splitmix63
41-
may be seeded with any value. Outputs of Splitmix63 may be used to to serially seed c[0] states
42-
of Collatz Generator by c[0] = (next_splitmix63() << 1) | 1; */
43-
44-
static uint64_t CG64_y = 123;
45-
46-
uint64_t next_splitmix63(void) {
47-
uint64_t CG64_z = (CG64_y += 0x9e3779b97f4a7c15) & 0x7fffffffffffffff;
48-
CG64_z = ((CG64_z ^ (CG64_z >> 30)) * 0xbf58476d1ce4e5b9) & 0x7fffffffffffffff;
49-
CG64_z = ((CG64_z ^ (CG64_z >> 27)) * 0x94d049bb133111eb) & 0x7fffffffffffffff;
50-
return CG64_z ^ (CG64_z >> 31);
40+
// call this to seed CG64_c[0]
41+
static inline void CG64_seed(uint64_t seed) {
42+
CG64_c[0] = (splitmix63_r(&seed) << 1) | 1;
5143
}
5244

53-
CG64_c[0] = (next_splitmix63() << 1) | 1;
54-
5545
static inline uint64_t CG64(void)
5646
{
57-
CG64_c[1] = (CG64_c[1] >> 1) * ((CG64_c[2] += CG64_c[1]) | 1) ^ (CG64_c[3] += CG64_c[0]);
58-
return CG64_c[2] >> 48 ^ CG64_c[1];
47+
CG64_c[1] = (CG64_c[1] >> 1) * ((CG64_c[2] += CG64_c[1]) | 1) ^ (CG64_c[3] += CG64_c[0]);
48+
return CG64_c[2] >> 48 ^ CG64_c[1];
5949
}
6050

61-
#endif // CG64_H
51+
#endif // CG64_H

source/splitmix63.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#ifndef SPLITMIX63_H
2+
#define SPLITMIX63_H
3+
4+
/* This is Splitmix63, modified Splitmix64 written in 2015 by Sebastiano Vigna. The state of Splitmix63
5+
may be seeded with any value. */
6+
7+
#include <stdint.h>
8+
9+
// state for splitmix63
10+
uint64_t splitmix63_x; /* The state can be seeded with any value. */
11+
12+
// call this one before calling splitmix64
13+
static inline void splitmix63_seed(uint64_t seed) { splitmix63_x = seed; }
14+
15+
// floor( ( (1+sqrt(5))/2 ) * 2**64 MOD 2**64)
16+
#define GOLDEN_GAMMA UINT64_C(0x9E3779B97F4A7C15)
17+
18+
static inline uint64_t splitmix63_r(uint64_t *seed) {
19+
uint64_t z = (*seed += GOLDEN_GAMMA) & 0x7fffffffffffffff;
20+
z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9) & 0x7fffffffffffffff;
21+
z = (z ^ (z >> 27)) * UINT64_C(0x94D049BB133111EB) & 0x7fffffffffffffff;
22+
return z ^ (z >> 31);
23+
}
24+
25+
static inline uint64_t splitmix63(void) {
26+
return splitmix63_r(&splitmix63_x);
27+
}
28+
29+
// returns the 32 least significant bits of a call to splitmix64
30+
// this is a simple (inlined) function call followed by a cast
31+
static inline uint32_t splitmix63_cast32(void) {
32+
return (uint32_t)splitmix63();
33+
}
34+
35+
// returns the value of splitmix64 "offset" steps from seed
36+
static inline uint64_t splitmix63_stateless(uint64_t seed, uint64_t offset) {
37+
seed += offset*GOLDEN_GAMMA;
38+
return splitmix63_r(&seed);
39+
}
40+
41+
#endif // SPLITMIX63_H

0 commit comments

Comments
 (0)