1#ifndef WFLCG_C_INCLUDE_GUARD
2#define WFLCG_C_INCLUDE_GUARD
6#define WFLCG_C_VERSION 0x010001
7#define WFLCG_C_VERSION_STRING "1.0.1"
8#define WFLCG_C_COPYRIGHT_STRING "WFLCG v" WFLCG_C_VERSION_STRING " (C)2019 Juha Nieminen"
10#define WFLCG_C_BUFFER_SIZE 16
14 uint32_t buffer[WFLCG_C_BUFFER_SIZE];
18inline void WFLCG_c_init_1_seed(
WFLCG_c* obj, uint32_t seed)
20 seed = seed * UINT32_C(2364742333) + UINT32_C(14567);
21 for(
unsigned i = 0; i < WFLCG_C_BUFFER_SIZE; ++i)
23 seed = seed * UINT32_C(2364742333) + UINT32_C(14567);
24 obj->buffer[i] = seed;
29inline void WFLCG_c_init_2_seeds(
WFLCG_c* obj, uint32_t seed1, uint32_t seed2)
31 seed1 = seed1 * UINT32_C(2364742333) + UINT32_C(14567);
32 seed2 = seed2 * UINT32_C(4112992229) + UINT32_C(12345);
33 for(
unsigned i = 0; i < WFLCG_C_BUFFER_SIZE; i += 2)
35 seed1 = seed1 * UINT32_C(2364742333) + UINT32_C(14567);
36 seed2 = seed2 * UINT32_C(4112992229) + UINT32_C(12345);
37 obj->buffer[i] = seed1;
38 obj->buffer[i+1] = seed2;
43inline void WFLCG_c_init_default(
WFLCG_c* obj)
45 WFLCG_c_init_1_seed(obj, 0);
48inline void WFLCG_c_refill_buffer(
WFLCG_c* obj)
50 static const uint32_t multipliers[WFLCG_C_BUFFER_SIZE] =
52 UINT32_C(3363461597), UINT32_C(3169304909), UINT32_C(2169304933), UINT32_C(2958304901),
53 UINT32_C(2738319061), UINT32_C(2738319613), UINT32_C(3238311437), UINT32_C(1238311381),
54 UINT32_C(1964742293), UINT32_C(1964743093), UINT32_C(2364742333), UINT32_C(2312912477),
55 UINT32_C(2312913061), UINT32_C(1312912501), UINT32_C(2812992317), UINT32_C(4112992229)
57 static const uint32_t increments[WFLCG_C_BUFFER_SIZE] =
59 UINT32_C(8346591), UINT32_C(18134761), UINT32_C(12345), UINT32_C(234567),
60 UINT32_C(14567), UINT32_C(12345), UINT32_C(123123), UINT32_C(11223345),
61 UINT32_C(123131), UINT32_C(83851), UINT32_C(14567), UINT32_C(134567),
62 UINT32_C(34567), UINT32_C(32145), UINT32_C(123093), UINT32_C(12345)
65 for(
unsigned i = 0; i < WFLCG_C_BUFFER_SIZE; ++i)
66 obj->buffer[i] = obj->buffer[i] * multipliers[i] + increments[i];
71inline uint32_t WFLCG_c_get_value(
WFLCG_c* obj)
73 if(obj->index == WFLCG_C_BUFFER_SIZE) WFLCG_c_refill_buffer(obj);
74 const uint32_t result = obj->buffer[obj->index] ^ (obj->buffer[obj->index] >> 24);
79inline float WFLCG_c_get_float(
WFLCG_c* obj)
81 if(obj->index == WFLCG_C_BUFFER_SIZE) WFLCG_c_refill_buffer(obj);
82 union {
float fValue; uint32_t uValue; } conv;
83 conv.uValue = UINT32_C(0x3F800000) | (obj->buffer[obj->index++] >> 9);
87inline double WFLCG_c_get_double(
WFLCG_c* obj)
89 union {
double dValue; uint64_t uValue; } conv;
90 conv.uValue = (UINT64_C(0x3FF0000000000000) | (((uint64_t)WFLCG_c_get_value(obj)) << 20));
94inline double WFLCG_c_get_double2(
WFLCG_c* obj)
96 if(obj->index == WFLCG_C_BUFFER_SIZE) WFLCG_c_refill_buffer(obj);
97 union {
double dValue; uint64_t uValue; } conv;
98 uint32_t value1 = obj->buffer[obj->index], value2 = obj->buffer[obj->index+1];
99 conv.uValue = (UINT64_C(0x3FF0000000000000) |
100 ((((uint64_t)value1) << 20) ^
101 (((uint64_t)value2) >> 4)));
106inline float WFLCG_c_buffer_element_float(
WFLCG_c* obj,
unsigned index)
108 union {
float fValue; uint32_t uValue; } conv;
109 conv.uValue = UINT32_C(0x3F800000) | (obj->buffer[index] >> 9);
113inline double WFLCG_c_buffer_element_double(
WFLCG_c* obj,
unsigned index)
115 union {
double dValue; uint64_t uValue; } conv;
116 uint32_t value = obj->buffer[index];
117 value ^= value >> 24;
118 conv.uValue = (UINT64_C(0x3FF0000000000000) | (((uint64_t)value) << 20));
122inline double WFLCG_c_buffer_element_double2(
WFLCG_c* obj,
unsigned index)
124 union {
double dValue; uint64_t uValue; } conv;
125 uint32_t value1 = obj->buffer[index], value2 = obj->buffer[index+1];
126 conv.uValue = (UINT64_C(0x3FF0000000000000) |
127 ((((uint64_t)value1) << 20) ^ (((uint64_t)value2) >> 4)));