-
Notifications
You must be signed in to change notification settings - Fork 5k
/
Copy pathxoshiro128pp.c
81 lines (62 loc) · 1.89 KB
/
xoshiro128pp.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include <minipal/xoshiro128pp.h>
// This code is a slightly modified version of the xoshiro128++ generator from http://prng.di.unimi.it/xoshiro128plusplus.c
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide.
See <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
static inline uint32_t rotl(const uint32_t x, int k) {
return (x << k) | (x >> (32 - k));
}
/* This is the jump function for the generator. It is equivalent
to 2^64 calls to next(); it can be used to generate 2^64
non-overlapping subsequences for parallel computations. */
static void jump(struct minipal_xoshiro128pp* pState) {
static const uint32_t JUMP[] = { 0x8764000b, 0xf542d2d3, 0x6fa035c3, 0x77f2db5b };
uint32_t* s = pState->s;
uint32_t s0 = 0;
uint32_t s1 = 0;
uint32_t s2 = 0;
uint32_t s3 = 0;
for (int i = 0; i < sizeof JUMP / sizeof * JUMP; i++)
for (int b = 0; b < 32; b++) {
if (JUMP[i] & UINT32_C(1) << b) {
s0 ^= s[0];
s1 ^= s[1];
s2 ^= s[2];
s3 ^= s[3];
}
minipal_xoshiro128pp_next(pState);
}
s[0] = s0;
s[1] = s1;
s[2] = s2;
s[3] = s3;
}
void minipal_xoshiro128pp_init(struct minipal_xoshiro128pp* pState, uint32_t seed) {
uint32_t* s = pState->s;
if (seed == 0)
{
seed = 997;
}
s[0] = seed;
s[1] = seed;
s[2] = seed;
s[3] = seed;
jump(pState);
}
uint32_t minipal_xoshiro128pp_next(struct minipal_xoshiro128pp* pState) {
uint32_t* s = pState->s;
const uint32_t result = rotl(s[0] + s[3], 7) + s[0];
const uint32_t t = s[1] << 9;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = rotl(s[3], 11);
return result;
}