summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTylo <[email protected]>2020-06-23 12:20:29 +0200
committerTylo <[email protected]>2020-06-23 12:20:29 +0200
commit7b50efc68e9339497345522fe7ffaf0833fb3869 (patch)
treea20719de61ab6a501670b56b96c4e2736b095968
parent7eec04b0777e66eb14c0adfc14d26ed2a6b5b2b9 (diff)
downloadSTC-modified-7b50efc68e9339497345522fe7ffaf0833fb3869.tar.gz
STC-modified-7b50efc68e9339497345522fe7ffaf0833fb3869.zip
Minor stuff on crandom. and STC_INLINE
-rw-r--r--examples/rngtest.c10
-rw-r--r--stc/cdefs.h8
-rw-r--r--stc/clist.h3
-rw-r--r--stc/crandom.h92
4 files changed, 56 insertions, 57 deletions
diff --git a/examples/rngtest.c b/examples/rngtest.c
index 4a39c4e6..f13306b0 100644
--- a/examples/rngtest.c
+++ b/examples/rngtest.c
@@ -55,14 +55,4 @@ int main(void)
}
difference = clock() - before;
printf("sfc64: %.02f, %zu\n", (float) difference / CLOCKS_PER_SEC, v);
-
-/*
- before = clock(); \
- v = 0;
- for (size_t i=0; i<NN; i++) {
- v += rand();
- }
- difference = clock() - before;
- printf("rand : %.02f, %zu\n", (float) difference / CLOCKS_PER_SEC, v);
-*/
} \ No newline at end of file
diff --git a/stc/cdefs.h b/stc/cdefs.h
index ae707ec1..fd66e2f8 100644
--- a/stc/cdefs.h
+++ b/stc/cdefs.h
@@ -28,17 +28,17 @@
#include <stdbool.h>
#if 0 // defined(_MSC_VER)
-# define STC_INLINE __forceinline
+# define STC_INLINE static __forceinline
#elif 0 // defined(__GNUC__)
-# define STC_INLINE inline __attribute((always_inline))
+# define STC_INLINE static inline __attribute((always_inline))
#else // don't force
-# define STC_INLINE inline
+# define STC_INLINE static inline
#endif
#if defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define STC_API extern
#else
-#define STC_API static STC_INLINE
+#define STC_API STC_INLINE
#endif
/* Macro overloading feature support: https://rextester.com/ONP80107 */
diff --git a/stc/clist.h b/stc/clist.h
index 9b1c37f1..81af6e53 100644
--- a/stc/clist.h
+++ b/stc/clist.h
@@ -23,6 +23,7 @@
#ifndef CLIST__H__
#define CLIST__H__
+#include <stdlib.h>
#include "cdefs.h"
/* Circular Singly-linked Lists.
@@ -221,7 +222,7 @@
} \
STC_API void \
clist_##tag##_sort(CList_##tag* self) { \
- CListNode__base* last = _clist_mergesort((CListNode__base *) self->last, clist_##tag##_sortCmp); \
+ CListNode__base* last = _clist_mergesort((CListNode__base *) self->last->next, clist_##tag##_sortCmp); \
self->last = (CListNode_##tag *) last; \
}
diff --git a/stc/crandom.h b/stc/crandom.h
index 167993e2..1e8ec6ee 100644
--- a/stc/crandom.h
+++ b/stc/crandom.h
@@ -8,15 +8,8 @@
* Mersenne Twister random number generator MT19937, 32 bit.
*/
-enum {
- mt19937_N = 624,
- mt19937_M = 397,
-};
-
-typedef struct mt19937 {
- uint32_t idx;
- uint32_t arr[mt19937_N];
-} mt19937_t;
+enum {mt19937_N = 624, mt19937_M = 397};
+typedef struct {uint32_t idx, arr[mt19937_N];} mt19937_t;
/* initializes state with a seed */
STC_API void mt19937_init(mt19937_t *state, uint32_t seed) {
@@ -39,7 +32,7 @@ STC_API mt19937_t mt19937_default(void) {
return state;
}
-/* generates a random number on [0, 0xffffffff]-interval */
+/* generates a random number in [0, 2^32)-interval */
STC_API uint32_t mt19937_rand(mt19937_t *state) {
enum {N = mt19937_N, M = mt19937_M};
@@ -71,7 +64,6 @@ STC_API uint32_t mt19937_rand(mt19937_t *state) {
/*
* rotate bits left uint64
*/
-
STC_INLINE uint64_t c_rotateLeft64(uint64_t x, int bits) {
return (x << bits) | (x >> (64 - bits));
}
@@ -79,7 +71,6 @@ STC_INLINE uint64_t c_rotateLeft64(uint64_t x, int bits) {
/*
* xoroshiro128** with splitmix64 seed initialization
*/
-
STC_API uint64_t splitmix64(uint64_t *state) {
uint64_t z = (*state += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
@@ -87,9 +78,7 @@ STC_API uint64_t splitmix64(uint64_t *state) {
return z ^ (z >> 31);
}
-typedef struct xoroshiro128ss {
- uint64_t s[2];
-} xoroshiro128ss_t;
+typedef struct {uint64_t s[2];} xoroshiro128ss_t;
STC_API xoroshiro128ss_t xoroshiro128ss_seed(uint64_t seed) {
xoroshiro128ss_t state;
@@ -99,12 +88,11 @@ STC_API xoroshiro128ss_t xoroshiro128ss_seed(uint64_t seed) {
}
STC_API uint64_t xoroshiro128ss_rand(xoroshiro128ss_t *state) {
- uint64_t *s = state->s, s1 = s[1];
- const uint64_t s0 = s[0];
- const uint64_t result = c_rotateLeft64(s0 * 5, 7) * 9;
- s1 ^= s0;
- s[0] = c_rotateLeft64(s0, 24) ^ s1 ^ (s1 << 16);
- s[1] = c_rotateLeft64(s1, 37);
+ uint64_t *s = state->s;
+ const uint64_t xo = s[0] ^ s[1];
+ const uint64_t result = c_rotateLeft64(s[0] * 5, 7) * 9;
+ s[0] = c_rotateLeft64(s[0], 24) ^ xo ^ (xo << 16);
+ s[1] = c_rotateLeft64(xo, 37);
return result;
}
@@ -123,40 +111,62 @@ STC_API void xoroshiro128ss_jump(xoroshiro128ss_t *state, bool longJump) {
}
/*
- * sfc32: http://pracrand.sourceforge.net
+ * xoshiro256**:
*/
+typedef struct {uint64_t s[4];} xoshiro256ss_t;
+
+STC_API uint64_t xoshiro256ss_rand(xoshiro256ss_t* state) {
+ uint64_t *s = state->s;
+ const uint64_t result = c_rotateLeft64(s[1] * 5, 7) * 9;
+ const uint64_t t = s[1] << 17;
+ s[2] ^= s[0];
+ s[3] ^= s[1];
+ s[1] ^= s[2];
+ s[0] ^= s[3];
+ s[2] ^= t;
+ s[3] = c_rotateLeft64(s[3], 45);
+ return result;
+}
-typedef struct sfc32 {uint32_t v[4];} sfc32_t;
+STC_API xoshiro256ss_t xoshiro256ss_seed(uint64_t seed) {
+ xoshiro256ss_t state;
+ for (int i=0; i<4; ++i) state.s[i] = splitmix64(&seed);
+ return state;
+}
+
+/*
+ * sfc32: http://pracrand.sourceforge.net
+ */
+typedef struct {uint32_t s[4];} sfc32_t;
STC_API uint32_t sfc32_rand(sfc32_t* state) {
- enum {LROT = 21, RSHIFT = 9, LSHIFT = 3};
- uint32_t *v = state->v;
- const uint32_t out = v[0] + v[1] + v[3]++;
- v[0] = v[1] ^ (v[1] >> RSHIFT);
- v[1] = v[2] + (v[2] << LSHIFT);
- v[2] = ((v[2] << LROT) | (v[2] >> (32 - LROT))) + out;
+ enum {LR=21, RS=9, LS=3};
+ uint32_t *s = state->s;
+ const uint32_t out = s[0] + s[1] + s[3]++;
+ s[0] = s[1] ^ (s[1] >> RS);
+ s[1] = s[2] + (s[2] << LS);
+ s[2] = ((s[2] << LR) | (s[2] >> (32 - LR))) + out;
return out;
}
STC_API sfc32_t sfc32_seed(const uint64_t seed) {
sfc32_t state = {{0, (uint32_t) seed, (uint32_t) (seed >> 32), 1}};
- for (int i = 0; i < 12; ++i) sfc32_rand(&state);
+ for (int i=0; i<12; ++i) sfc32_rand(&state);
return state;
}
/*
* sfc64: http://pracrand.sourceforge.net
*/
-
-typedef struct sfc64 {uint64_t v[4];} sfc64_t;
+typedef struct {uint64_t s[4];} sfc64_t;
STC_API uint64_t sfc64_rand(sfc64_t* state) {
- enum {LROT = 24, RSHIFT = 11, LSHIFT = 3};
- uint64_t *v = state->v;
- const uint64_t out = v[0] + v[1] + v[3]++;
- v[0] = v[1] ^ (v[1] >> RSHIFT);
- v[1] = v[2] + (v[2] << LSHIFT);
- v[2] = ((v[2] << LROT) | (v[2] >> (64 - LROT))) + out;
+ enum {LR=24, RS=11, LS=3};
+ uint64_t *s = state->s;
+ const uint64_t out = s[0] + s[1] + s[3]++;
+ s[0] = s[1] ^ (s[1] >> RS);
+ s[1] = s[2] + (s[2] << LS);
+ s[2] = ((s[2] << LR) | (s[2] >> (64 - LR))) + out;
return out;
}
@@ -169,13 +179,12 @@ STC_API sfc64_t sfc64_seed(const uint64_t seed) {
/*
* convert random int number to float in [0, 1) range.
*/
-
-STC_API float c_randToFloat(uint32_t rnd) {
+STC_INLINE float c_randToFloat(uint32_t rnd) {
union {uint32_t i; float f;} u = {0x3F800000u | (rnd >> 9)};
return u.f - 1.0f;
}
-STC_API double c_randToDouble(uint64_t rnd) {
+STC_INLINE double c_randToDouble(uint64_t rnd) {
union {uint64_t i; double f;} u = {0x3FF0000000000000ull | (rnd >> 12)};
return u.f - 1.0;
}
@@ -183,7 +192,6 @@ STC_API double c_randToDouble(uint64_t rnd) {
/*
* siphash implementation.
*/
-
#if defined(_WIN32) || (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
STC_INLINE uint64_t c_le64ToHost(uint64_t x) { return x; }
#elif defined(__APPLE__)