Line data Source code
1 : /* 2 : This 64 bit pseudo random number generator is based on the engine 3 : written by Sebastiano Vigna from Dipartimento di Informatica of the 4 : Università degli Studi di Milano. The original source code can be 5 : found here http://xoshiro.di.unimi.it/xoshiro256starstar.c. The 6 : engine is supposed to perform very well on various random engine 7 : benchmarks. 8 : The original author offered his work to the public domain per the 9 : following original comment. 10 : */ 11 : 12 : /* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) 13 : 14 : To the extent possible under law, the author has dedicated all copyright 15 : and related and neighboring rights to this software to the public domain 16 : worldwide. This software is distributed without any warranty. 17 : 18 : See <http://creativecommons.org/publicdomain/zero/1.0/>. */ 19 : 20 : typedef uint64_t random_state_engine[4]; 21 : 22 : static inline uint64_t 23 51447868 : rotl(const uint64_t x, int k) 24 : { 25 51447868 : return (x << k) | (x >> (64 - k)); 26 : } 27 : 28 : static inline void 29 686 : init_random_state_engine(random_state_engine engine, uint64_t seed) 30 : { 31 3430 : for (int i = 0; i < 4; i++) { 32 : /* we use the splitmix64 generator to generate the 4 33 : * values in the state array from the given seed. 34 : * This code is adapted from 35 : * http://xoshiro.di.unimi.it/splitmix64.c which was 36 : * put in the public domain in the same way as the 37 : * "next" function below. */ 38 2744 : uint64_t z = (seed += 0x9e3779b97f4a7c15); 39 2744 : z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; 40 2744 : z = (z ^ (z >> 27)) * 0x94d049bb133111eb; 41 2744 : engine[i] = z ^ (z >> 31); 42 : } 43 686 : } 44 : 45 : static inline uint64_t 46 51447868 : next(random_state_engine rse) 47 : { 48 51447868 : const uint64_t output = rotl(rse[1] * 5, 7) * 9; 49 : 50 51447868 : const uint64_t t = rse[1] << 17; 51 : 52 51447868 : rse[2] ^= rse[0]; 53 51447868 : rse[3] ^= rse[1]; 54 51447868 : rse[1] ^= rse[2]; 55 51447868 : rse[0] ^= rse[3]; 56 : 57 51447868 : rse[2] ^= t; 58 : 59 51447868 : rse[3] = rotl(rse[3], 45); 60 : 61 51447868 : return output; 62 : }