Hi
I'm a GNU maintainer, and want to contribute some new rng's, because I
stepped over them when updating the DIEHARDER testsuite.
I'm also maintainer of smhasher.

Do you need a seperate FSF copyright assignment? I'm already on file at
savannah.

-- 
Reini Urban
From 5d8f4c83ffb39fa5e0584c328533ea74cb0a9d42 Mon Sep 17 00:00:00 2001
From: Reini Urban <rur...@cpan.org>
Date: Fri, 16 Oct 2020 10:52:57 +0200
Subject: [PATCH 1/3] Update rng benchmarks with a fast Ryzen 3

This includes now the numbers for all current 66 rng's,
not just a selection of 18.
---
 doc/rng.rst          | 74 ++++++++++++++++++++++++++++++++-------
 doc_texinfo/rng.texi | 82 +++++++++++++++++++++++++++++++++++---------
 2 files changed, 126 insertions(+), 30 deletions(-)

diff --git doc/rng.rst doc/rng.rst
index 6aa731cc..6d736cac 100644
--- doc/rng.rst
+++ doc/rng.rst
@@ -1099,24 +1099,72 @@ Performance
 .. represented by the :code:`random` generator below.  These generators are
 .. fast but have the lowest statistical quality.
 
-The following table shows the relative performance of a selection the
+The following table shows the relative performance of a all
 available random number generators.  The fastest simulation quality
 generators are :code:`taus`, :code:`gfsr4` and :code:`mt19937`.  The
 generators which offer the best mathematically-proven quality are those
 based on the RANLUX algorithm::
 
-  1754 k ints/sec,    870 k doubles/sec, taus
-  1613 k ints/sec,    855 k doubles/sec, gfsr4
-  1370 k ints/sec,    769 k doubles/sec, mt19937
-   565 k ints/sec,    571 k doubles/sec, ranlxs0
-   400 k ints/sec,    405 k doubles/sec, ranlxs1
-   490 k ints/sec,    389 k doubles/sec, mrg
-   407 k ints/sec,    297 k doubles/sec, ranlux
-   243 k ints/sec,    254 k doubles/sec, ranlxd1
-   251 k ints/sec,    253 k doubles/sec, ranlxs2
-   238 k ints/sec,    215 k doubles/sec, cmrg
-   247 k ints/sec,    198 k doubles/sec, ranlux389
-   141 k ints/sec,    140 k doubles/sec, ranlxd2
+  328964 k ints/sec, 309224 k doubles/sec, transputer
+  328636 k ints/sec, 309094 k doubles/sec, waterman14
+  319741 k ints/sec, 297242 k doubles/sec, borosh13
+  319059 k ints/sec, 271855 k doubles/sec, ran3
+  314252 k ints/sec, 281049 k doubles/sec, r250
+  310345 k ints/sec, 293818 k doubles/sec, jsf
+  298077 k ints/sec, 298469 k doubles/sec, jsf64
+  295887 k ints/sec, 299276 k doubles/sec, coveyou
+  295145 k ints/sec, 298620 k doubles/sec, vax
+  293844 k ints/sec, 136665 k doubles/sec, ranmar
+  293525 k ints/sec, 289265 k doubles/sec, random-glibc2
+  293315 k ints/sec, 297062 k doubles/sec, randu
+  293195 k ints/sec, 288070 k doubles/sec, random64-glibc2
+  293123 k ints/sec, 288626 k doubles/sec, random-bsd
+  292932 k ints/sec, 289939 k doubles/sec, random128-bsd
+  291894 k ints/sec, 288411 k doubles/sec, random-libc5
+  291792 k ints/sec, 287893 k doubles/sec, random64-libc5
+  291670 k ints/sec, 272732 k doubles/sec, random32-libc5
+  291389 k ints/sec, 288216 k doubles/sec, random32-glibc2
+  290627 k ints/sec, 277519 k doubles/sec, uni
+  289957 k ints/sec, 276028 k doubles/sec, random256-glibc2
+  289719 k ints/sec, 278012 k doubles/sec, random256-bsd
+  286205 k ints/sec, 278385 k doubles/sec, random256-libc5
+  284937 k ints/sec, 282090 k doubles/sec, random128-glibc2
+  284853 k ints/sec, 267730 k doubles/sec, random64-bsd
+  284797 k ints/sec, 269101 k doubles/sec, uni32
+  283980 k ints/sec, 285506 k doubles/sec, random8-glibc2
+  283802 k ints/sec, 280524 k doubles/sec, random8-bsd
+  283015 k ints/sec, 285540 k doubles/sec, random8-libc5
+  282902 k ints/sec, 285138 k doubles/sec, rand
+  282296 k ints/sec, 282613 k doubles/sec, random32-bsd
+  278943 k ints/sec, 261021 k doubles/sec, mt19937
+  271239 k ints/sec,  55285 k doubles/sec, ranf
+  265568 k ints/sec, 263181 k doubles/sec, gfsr4
+  264719 k ints/sec, 251332 k doubles/sec, taus
+  262505 k ints/sec,  52593 k doubles/sec, rand48
+  261220 k ints/sec, 245894 k doubles/sec, tt800
+  247667 k ints/sec, 257275 k doubles/sec, random128-libc5
+  233522 k ints/sec, 225526 k doubles/sec, taus113
+  198365 k ints/sec, 199142 k doubles/sec, knuthran
+  177301 k ints/sec, 175731 k doubles/sec, slatec
+  155473 k ints/sec, 155889 k doubles/sec, fishman20
+  152459 k ints/sec, 153368 k doubles/sec, minstd
+  150635 k ints/sec, 150672 k doubles/sec, ran1
+  148195 k ints/sec, 139760 k doubles/sec, fishman2x
+  146463 k ints/sec, 151964 k doubles/sec, ran0
+  137318 k ints/sec, 140146 k doubles/sec, lecuyer21
+  119559 k ints/sec, 118447 k doubles/sec, ran2
+  106604 k ints/sec,  97263 k doubles/sec, zuf
+   85861 k ints/sec,  82312 k doubles/sec, mrg
+   69997 k ints/sec,  71964 k doubles/sec, fishman18
+   53427 k ints/sec,  53351 k doubles/sec, cmrg
+   37676 k ints/sec,  40992 k doubles/sec, knuthran2
+   35773 k ints/sec,  35799 k doubles/sec, ranlxs0
+   23627 k ints/sec,  23611 k doubles/sec, ranlxs1
+   20209 k ints/sec,  20051 k doubles/sec, ranlux
+   13674 k ints/sec,  13634 k doubles/sec, ranlxs2
+   13671 k ints/sec,  13614 k doubles/sec, ranlxd1
+   11852 k ints/sec,  11536 k doubles/sec, ranlux389
+    7430 k ints/sec,   7427 k doubles/sec, ranlxd2
 
 Examples
 ========
diff --git doc_texinfo/rng.texi doc_texinfo/rng.texi
index d2168c09..feff90f1 100644
--- doc_texinfo/rng.texi
+++ doc_texinfo/rng.texi
@@ -1336,29 +1336,77 @@ The seed specifies the initial value,
 @comment ./benchmark > tmp; cat tmp | perl -n -e '($n,$s) = split(" ",$_); printf("%17s ",$n); print "-" x ($s/1e5), "\n";'
 @comment
 
-The following table shows the relative performance of a selection the
-available random number generators.  The fastest simulation quality
-generators are @code{taus}, @code{gfsr4} and @code{mt19937}.  The
-generators which offer the best mathematically-proven quality are those
-based on the @sc{ranlux} algorithm.
+The following table shows the relative performance of all available
+random number generators.  The fastest simulation quality generators
+are @code{taus}, @code{gfsr4} and @code{mt19937}.  The generators
+which offer the best mathematically-proven quality are those based on
+the @sc{ranlux} algorithm.
 
 @comment The large number of generators based on single linear congruences are
 @comment represented by the @code{random} generator below.  These generators are
 @comment fast but have the lowest statistical quality.
 
 @example
-1754 k ints/sec,    870 k doubles/sec, taus
-1613 k ints/sec,    855 k doubles/sec, gfsr4
-1370 k ints/sec,    769 k doubles/sec, mt19937
- 565 k ints/sec,    571 k doubles/sec, ranlxs0
- 400 k ints/sec,    405 k doubles/sec, ranlxs1
- 490 k ints/sec,    389 k doubles/sec, mrg
- 407 k ints/sec,    297 k doubles/sec, ranlux
- 243 k ints/sec,    254 k doubles/sec, ranlxd1
- 251 k ints/sec,    253 k doubles/sec, ranlxs2
- 238 k ints/sec,    215 k doubles/sec, cmrg
- 247 k ints/sec,    198 k doubles/sec, ranlux389
- 141 k ints/sec,    140 k doubles/sec, ranlxd2
+  328964 k ints/sec, 309224 k doubles/sec, transputer
+  328636 k ints/sec, 309094 k doubles/sec, waterman14
+  319741 k ints/sec, 297242 k doubles/sec, borosh13
+  319059 k ints/sec, 271855 k doubles/sec, ran3
+  314252 k ints/sec, 281049 k doubles/sec, r250
+  310345 k ints/sec, 293818 k doubles/sec, jsf
+  298077 k ints/sec, 298469 k doubles/sec, jsf64
+  295887 k ints/sec, 299276 k doubles/sec, coveyou
+  295145 k ints/sec, 298620 k doubles/sec, vax
+  293844 k ints/sec, 136665 k doubles/sec, ranmar
+  293525 k ints/sec, 289265 k doubles/sec, random-glibc2
+  293315 k ints/sec, 297062 k doubles/sec, randu
+  293195 k ints/sec, 288070 k doubles/sec, random64-glibc2
+  293123 k ints/sec, 288626 k doubles/sec, random-bsd
+  292932 k ints/sec, 289939 k doubles/sec, random128-bsd
+  291894 k ints/sec, 288411 k doubles/sec, random-libc5
+  291792 k ints/sec, 287893 k doubles/sec, random64-libc5
+  291670 k ints/sec, 272732 k doubles/sec, random32-libc5
+  291389 k ints/sec, 288216 k doubles/sec, random32-glibc2
+  290627 k ints/sec, 277519 k doubles/sec, uni
+  289957 k ints/sec, 276028 k doubles/sec, random256-glibc2
+  289719 k ints/sec, 278012 k doubles/sec, random256-bsd
+  286205 k ints/sec, 278385 k doubles/sec, random256-libc5
+  284937 k ints/sec, 282090 k doubles/sec, random128-glibc2
+  284853 k ints/sec, 267730 k doubles/sec, random64-bsd
+  284797 k ints/sec, 269101 k doubles/sec, uni32
+  283980 k ints/sec, 285506 k doubles/sec, random8-glibc2
+  283802 k ints/sec, 280524 k doubles/sec, random8-bsd
+  283015 k ints/sec, 285540 k doubles/sec, random8-libc5
+  282902 k ints/sec, 285138 k doubles/sec, rand
+  282296 k ints/sec, 282613 k doubles/sec, random32-bsd
+  278943 k ints/sec, 261021 k doubles/sec, mt19937
+  271239 k ints/sec,  55285 k doubles/sec, ranf
+  265568 k ints/sec, 263181 k doubles/sec, gfsr4
+  264719 k ints/sec, 251332 k doubles/sec, taus
+  262505 k ints/sec,  52593 k doubles/sec, rand48
+  261220 k ints/sec, 245894 k doubles/sec, tt800
+  247667 k ints/sec, 257275 k doubles/sec, random128-libc5
+  233522 k ints/sec, 225526 k doubles/sec, taus113
+  198365 k ints/sec, 199142 k doubles/sec, knuthran
+  177301 k ints/sec, 175731 k doubles/sec, slatec
+  155473 k ints/sec, 155889 k doubles/sec, fishman20
+  152459 k ints/sec, 153368 k doubles/sec, minstd
+  150635 k ints/sec, 150672 k doubles/sec, ran1
+  148195 k ints/sec, 139760 k doubles/sec, fishman2x
+  146463 k ints/sec, 151964 k doubles/sec, ran0
+  137318 k ints/sec, 140146 k doubles/sec, lecuyer21
+  119559 k ints/sec, 118447 k doubles/sec, ran2
+  106604 k ints/sec,  97263 k doubles/sec, zuf
+   85861 k ints/sec,  82312 k doubles/sec, mrg
+   69997 k ints/sec,  71964 k doubles/sec, fishman18
+   53427 k ints/sec,  53351 k doubles/sec, cmrg
+   37676 k ints/sec,  40992 k doubles/sec, knuthran2
+   35773 k ints/sec,  35799 k doubles/sec, ranlxs0
+   23627 k ints/sec,  23611 k doubles/sec, ranlxs1
+   20209 k ints/sec,  20051 k doubles/sec, ranlux
+   13674 k ints/sec,  13634 k doubles/sec, ranlxs2
+   13671 k ints/sec,  13614 k doubles/sec, ranlxd1
+   11852 k ints/sec,  11536 k doubles/sec, ranlux389
+    7430 k ints/sec,   7427 k doubles/sec, ranlxd2
 @end example
 
 @node Random Number Generator Examples
-- 
2.26.2

From bedc39f2af29b0722980e97f7ae617b401ed025a Mon Sep 17 00:00:00 2001
From: Reini Urban <rur...@cpan.org>
Date: Fri, 16 Oct 2020 11:32:36 +0200
Subject: [PATCH 3/3] update ChangeLogs et al

---
 AUTHORS               | 1 +
 THANKS                | 2 ++
 doc_texinfo/ChangeLog | 5 +++++
 rng/ChangeLog         | 4 ++++
 4 files changed, 12 insertions(+)

diff --git AUTHORS AUTHORS
index 331875c5..b3730c1d 100644
--- AUTHORS
+++ AUTHORS
@@ -30,3 +30,4 @@ Patrick Alken <patrick.al...@colorado.edu> - nonsymmetric and generalized
 Rhys Ulerich (rhys.uler...@gmail.com) - multisets
 Pavel Holoborodko <pa...@holoborodko.com> - fixed order Gauss-Legendre quadrature
 Pedro Gonnet <gon...@maths.ox.ac.uk> - CQUAD integration routines.
+Reini Urban <rur...@cpan.org> - jsf and xoshori* rng's
diff --git THANKS THANKS
index 80fe5ea4..9f725740 100644
--- THANKS
+++ THANKS
@@ -511,3 +511,5 @@ evaluation and ode improvements
 
 * Raymond Rogers <raymond.roger...@gmail.com> - bug fixes for confluent
   hypergeometric functions
+
+* Reini Urban <rur...@cpan.org> - added the jsf and xoshori* rng's
diff --git doc_texinfo/ChangeLog doc_texinfo/ChangeLog
index 96288ec5..70d0b25a 100644
--- doc_texinfo/ChangeLog
+++ doc_texinfo/ChangeLog
@@ -1,3 +1,8 @@
+2012-10-16  Reini Urban <rur...@cpan.org>
+
+	* rng.texi: All benchmarks numbers for all rng's, also the
+        new jsf and xoshiro* ones. Calculated with a Ryzen 3.
+
 2017-01-07  Rhys Ulerich  <rhys.uler...@gmail.com>
 
 	* vectors.texi: Document zero-length block/vector/matrix
diff --git rng/ChangeLog rng/ChangeLog
index 8e79fcaf..3ce3df83 100644
--- rng/ChangeLog
+++ rng/ChangeLog
@@ -1,3 +1,7 @@
+2012-10-16  Reini Urban <rur...@cpan.org>
+
+	* jsf.c, xoshiro32bit.c, xoroshiro64bit.c: Added.
+
 2012-09-10  Rhys Ulerich <rhys.uler...@gmail.com>
 
 	* ranf.c Add include for gsl_sys.h to fix MSVC build.
-- 
2.26.2

From feb34ae5c4341882f4ec3ddfc1695388255c6717 Mon Sep 17 00:00:00 2001
From: Reini Urban <rur...@cpan.org>
Date: Fri, 16 Oct 2020 11:11:24 +0200
Subject: [PATCH 2/3] gsl_rng_xoshiro and xoroshiro variants (32 and 64bit)

---
 doc/rng.rst          |  11 ++
 doc_texinfo/rng.texi |  11 ++
 rng/Makefile.am      |   2 +-
 rng/benchmark.c      |  11 ++
 rng/gsl_rng.h        |  11 ++
 rng/test.c           |  24 +++
 rng/types.c          |  11 ++
 rng/xoroshiro64bit.c | 339 +++++++++++++++++++++++++++++++++++++++++++
 rng/xoshiro32bit.c   | 276 +++++++++++++++++++++++++++++++++++
 9 files changed, 695 insertions(+), 1 deletion(-)
 create mode 100644 rng/xoroshiro64bit.c
 create mode 100644 rng/xoshiro32bit.c

diff --git doc/rng.rst doc/rng.rst
index 6d736cac..1bfa097b 100644
--- doc/rng.rst
+++ doc/rng.rst
@@ -1111,8 +1111,12 @@ based on the RANLUX algorithm::
   319059 k ints/sec, 271855 k doubles/sec, ran3
   314252 k ints/sec, 281049 k doubles/sec, r250
   310345 k ints/sec, 293818 k doubles/sec, jsf
+  306351 k ints/sec, 295357 k doubles/sec, xoroshiro64**
+  306348 k ints/sec, 294652 k doubles/sec, xoshiro256+
   298077 k ints/sec, 298469 k doubles/sec, jsf64
+  296997 k ints/sec, 268763 k doubles/sec, xoroshiro64*
   295887 k ints/sec, 299276 k doubles/sec, coveyou
+  295622 k ints/sec, 297637 k doubles/sec, xoroshiro128+
   295145 k ints/sec, 298620 k doubles/sec, vax
   293844 k ints/sec, 136665 k doubles/sec, ranmar
   293525 k ints/sec, 289265 k doubles/sec, random-glibc2
@@ -1127,21 +1131,28 @@ based on the RANLUX algorithm::
   290627 k ints/sec, 277519 k doubles/sec, uni
   289957 k ints/sec, 276028 k doubles/sec, random256-glibc2
   289719 k ints/sec, 278012 k doubles/sec, random256-bsd
+  286423 k ints/sec, 274391 k doubles/sec, xoshiro256++
   286205 k ints/sec, 278385 k doubles/sec, random256-libc5
+  285164 k ints/sec, 279405 k doubles/sec, xoshiro128+
   284937 k ints/sec, 282090 k doubles/sec, random128-glibc2
   284853 k ints/sec, 267730 k doubles/sec, random64-bsd
   284797 k ints/sec, 269101 k doubles/sec, uni32
   283980 k ints/sec, 285506 k doubles/sec, random8-glibc2
   283802 k ints/sec, 280524 k doubles/sec, random8-bsd
+  283488 k ints/sec, 283380 k doubles/sec, xoroshiro128**
   283015 k ints/sec, 285540 k doubles/sec, random8-libc5
   282902 k ints/sec, 285138 k doubles/sec, rand
   282296 k ints/sec, 282613 k doubles/sec, random32-bsd
+  280662 k ints/sec, 289208 k doubles/sec, xoshiro256**
   278943 k ints/sec, 261021 k doubles/sec, mt19937
+  272474 k ints/sec, 271866 k doubles/sec, xoroshiro128++
   271239 k ints/sec,  55285 k doubles/sec, ranf
+  269604 k ints/sec, 247058 k doubles/sec, xoshiro128++
   265568 k ints/sec, 263181 k doubles/sec, gfsr4
   264719 k ints/sec, 251332 k doubles/sec, taus
   262505 k ints/sec,  52593 k doubles/sec, rand48
   261220 k ints/sec, 245894 k doubles/sec, tt800
+  260970 k ints/sec, 254503 k doubles/sec, xoshiro128**
   247667 k ints/sec, 257275 k doubles/sec, random128-libc5
   233522 k ints/sec, 225526 k doubles/sec, taus113
   198365 k ints/sec, 199142 k doubles/sec, knuthran
diff --git doc_texinfo/rng.texi doc_texinfo/rng.texi
index feff90f1..3c0acf6a 100644
--- doc_texinfo/rng.texi
+++ doc_texinfo/rng.texi
@@ -1353,8 +1353,12 @@ the @sc{ranlux} algorithm.
   319059 k ints/sec, 271855 k doubles/sec, ran3
   314252 k ints/sec, 281049 k doubles/sec, r250
   310345 k ints/sec, 293818 k doubles/sec, jsf
+  306351 k ints/sec, 295357 k doubles/sec, xoroshiro64**
+  306348 k ints/sec, 294652 k doubles/sec, xoshiro256+
   298077 k ints/sec, 298469 k doubles/sec, jsf64
+  296997 k ints/sec, 268763 k doubles/sec, xoroshiro64*
   295887 k ints/sec, 299276 k doubles/sec, coveyou
+  295622 k ints/sec, 297637 k doubles/sec, xoroshiro128+
   295145 k ints/sec, 298620 k doubles/sec, vax
   293844 k ints/sec, 136665 k doubles/sec, ranmar
   293525 k ints/sec, 289265 k doubles/sec, random-glibc2
@@ -1369,21 +1373,28 @@ the @sc{ranlux} algorithm.
   290627 k ints/sec, 277519 k doubles/sec, uni
   289957 k ints/sec, 276028 k doubles/sec, random256-glibc2
   289719 k ints/sec, 278012 k doubles/sec, random256-bsd
+  286423 k ints/sec, 274391 k doubles/sec, xoshiro256++
   286205 k ints/sec, 278385 k doubles/sec, random256-libc5
+  285164 k ints/sec, 279405 k doubles/sec, xoshiro128+
   284937 k ints/sec, 282090 k doubles/sec, random128-glibc2
   284853 k ints/sec, 267730 k doubles/sec, random64-bsd
   284797 k ints/sec, 269101 k doubles/sec, uni32
   283980 k ints/sec, 285506 k doubles/sec, random8-glibc2
   283802 k ints/sec, 280524 k doubles/sec, random8-bsd
+  283488 k ints/sec, 283380 k doubles/sec, xoroshiro128**
   283015 k ints/sec, 285540 k doubles/sec, random8-libc5
   282902 k ints/sec, 285138 k doubles/sec, rand
   282296 k ints/sec, 282613 k doubles/sec, random32-bsd
+  280662 k ints/sec, 289208 k doubles/sec, xoshiro256**
   278943 k ints/sec, 261021 k doubles/sec, mt19937
+  272474 k ints/sec, 271866 k doubles/sec, xoroshiro128++
   271239 k ints/sec,  55285 k doubles/sec, ranf
+  269604 k ints/sec, 247058 k doubles/sec, xoshiro128++
   265568 k ints/sec, 263181 k doubles/sec, gfsr4
   264719 k ints/sec, 251332 k doubles/sec, taus
   262505 k ints/sec,  52593 k doubles/sec, rand48
   261220 k ints/sec, 245894 k doubles/sec, tt800
+  260970 k ints/sec, 254503 k doubles/sec, xoshiro128**
   247667 k ints/sec, 257275 k doubles/sec, random128-libc5
   233522 k ints/sec, 225526 k doubles/sec, taus113
   198365 k ints/sec, 199142 k doubles/sec, knuthran
diff --git rng/Makefile.am rng/Makefile.am
index 71ad56f4..ae52c302 100644
--- rng/Makefile.am
+++ rng/Makefile.am
@@ -5,7 +5,7 @@ pkginclude_HEADERS = gsl_rng.h
 
 AM_CPPFLAGS = -I$(top_srcdir)
 
-libgslrng_la_SOURCES = borosh13.c cmrg.c coveyou.c default.c file.c fishman18.c fishman20.c fishman2x.c gfsr4.c knuthran2.c knuthran.c knuthran2002.c lecuyer21.c minstd.c mrg.c mt.c jsf.c r250.c ran0.c ran1.c ran2.c ran3.c rand48.c rand.c random.c randu.c ranf.c ranlux.c ranlxd.c ranlxs.c ranmar.c rng.c slatec.c taus.c taus113.c transputer.c tt.c types.c uni32.c uni.c vax.c waterman14.c zuf.c inline.c
+libgslrng_la_SOURCES = borosh13.c cmrg.c coveyou.c default.c file.c fishman18.c fishman20.c fishman2x.c gfsr4.c knuthran2.c knuthran.c knuthran2002.c lecuyer21.c minstd.c mrg.c mt.c jsf.c r250.c ran0.c ran1.c ran2.c ran3.c rand48.c rand.c random.c randu.c ranf.c ranlux.c ranlxd.c ranlxs.c ranmar.c rng.c slatec.c taus.c taus113.c transputer.c tt.c types.c uni32.c uni.c vax.c waterman14.c zuf.c xoshiro32bit.c xoroshiro64bit.c inline.c
 
 CLEANFILES = test.dat
 
diff --git rng/benchmark.c rng/benchmark.c
index 71cf45c1..fa665396 100644
--- rng/benchmark.c
+++ rng/benchmark.c
@@ -93,6 +93,17 @@ main (void)
   benchmark(gsl_rng_zuf);
   benchmark(gsl_rng_jsf);
   benchmark(gsl_rng_jsf64);
+  benchmark(gsl_rng_xoshiro128_pp);
+  benchmark(gsl_rng_xoshiro128_ss);
+  benchmark(gsl_rng_xoshiro128_p);
+  benchmark(gsl_rng_xoroshiro64_ss);
+  benchmark(gsl_rng_xoroshiro64_s);
+  benchmark(gsl_rng_xoroshiro128_pp);
+  benchmark(gsl_rng_xoroshiro128_ss);
+  benchmark(gsl_rng_xoroshiro128_p);
+  benchmark(gsl_rng_xoshiro256_pp);
+  benchmark(gsl_rng_xoshiro256_ss);
+  benchmark(gsl_rng_xoshiro256_p);
 
   return 0;
 }
diff --git rng/gsl_rng.h rng/gsl_rng.h
index 1e3dc61f..dd728105 100644
--- rng/gsl_rng.h
+++ rng/gsl_rng.h
@@ -123,6 +123,17 @@ GSL_VAR const gsl_rng_type *gsl_rng_waterman14;
 GSL_VAR const gsl_rng_type *gsl_rng_zuf;
 GSL_VAR const gsl_rng_type *gsl_rng_jsf;
 GSL_VAR const gsl_rng_type *gsl_rng_jsf64;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro128_pp;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro128_ss;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro128_p;
+GSL_VAR const gsl_rng_type *gsl_rng_xoroshiro64_ss;
+GSL_VAR const gsl_rng_type *gsl_rng_xoroshiro64_s;
+GSL_VAR const gsl_rng_type *gsl_rng_xoroshiro128_pp;
+GSL_VAR const gsl_rng_type *gsl_rng_xoroshiro128_ss;
+GSL_VAR const gsl_rng_type *gsl_rng_xoroshiro128_p;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro256_pp;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro256_ss;
+GSL_VAR const gsl_rng_type *gsl_rng_xoshiro256_p;
 
 const gsl_rng_type ** gsl_rng_types_setup(void);
 
diff --git rng/test.c rng/test.c
index e8a29ecd..48849cde 100644
--- rng/test.c
+++ rng/test.c
@@ -181,9 +181,22 @@ main (void)
   rng_test (gsl_rng_ranf, 0, 10000, 2152890433UL);
   rng_test (gsl_rng_ranf, 2, 10000, 339327233);
 
+  // 0 seed disallowed!
   rng_test (gsl_rng_jsf, 1, 10000, 210975159);
   rng_test (gsl_rng_jsf64, 1, 10000, 10988883387291576526UL);
 
+  rng_test (gsl_rng_xoshiro128_pp, 1, 10000, 3171859155UL);
+  rng_test (gsl_rng_xoshiro128_ss, 1, 10000, 1566019434UL);
+  rng_test (gsl_rng_xoshiro128_p, 1, 10000, 2752886404UL);
+  rng_test (gsl_rng_xoroshiro64_ss, 1, 10000, 786513473UL);
+  rng_test (gsl_rng_xoroshiro64_s, 1, 10000, 1803433264UL);
+  rng_test (gsl_rng_xoroshiro128_pp, 1, 10000, 6396584900321662142UL);
+  rng_test (gsl_rng_xoroshiro128_ss, 1, 10000, 2916662311688245179UL);
+  rng_test (gsl_rng_xoroshiro128_p, 1, 10000, 15011876659380427599UL);
+  rng_test (gsl_rng_xoshiro256_pp, 1, 10000, 13241388721673015269UL);
+  rng_test (gsl_rng_xoshiro256_ss, 1, 10000, 5864433267201140791UL);
+  rng_test (gsl_rng_xoshiro256_p, 1, 10000, 4624912334093259206UL);
+
   /* Test constant relationship between int and double functions */
 
   for (r = rngs ; *r != 0; r++)
@@ -226,6 +239,17 @@ main (void)
   rng_seed_test (gsl_rng_gfsr4);
   rng_seed_test (gsl_rng_jsf);
   rng_seed_test (gsl_rng_jsf64);
+  rng_seed_test (gsl_rng_xoshiro128_pp);
+  rng_seed_test (gsl_rng_xoshiro128_ss);
+  rng_seed_test (gsl_rng_xoshiro128_p);
+  rng_seed_test (gsl_rng_xoroshiro64_ss);
+  rng_seed_test (gsl_rng_xoroshiro64_s);
+  rng_seed_test (gsl_rng_xoroshiro128_pp);
+  rng_seed_test (gsl_rng_xoroshiro128_ss);
+  rng_seed_test (gsl_rng_xoroshiro128_p);
+  rng_seed_test (gsl_rng_xoshiro256_pp);
+  rng_seed_test (gsl_rng_xoshiro256_ss);
+  rng_seed_test (gsl_rng_xoshiro256_p);
 #endif
 
   exit (gsl_test_summary ());
diff --git rng/types.c rng/types.c
index d550cf76..1af05b66 100644
--- rng/types.c
+++ rng/types.c
@@ -96,6 +96,17 @@ gsl_rng_types_setup (void)
   ADD(gsl_rng_zuf);
   ADD(gsl_rng_jsf);
   ADD(gsl_rng_jsf64);
+  ADD(gsl_rng_xoshiro128_pp);
+  ADD(gsl_rng_xoshiro128_ss);
+  ADD(gsl_rng_xoshiro128_p);
+  ADD(gsl_rng_xoroshiro64_ss);
+  ADD(gsl_rng_xoroshiro64_s);
+  ADD(gsl_rng_xoroshiro128_pp);
+  ADD(gsl_rng_xoroshiro128_ss);
+  ADD(gsl_rng_xoroshiro128_p);
+  ADD(gsl_rng_xoshiro256_pp);
+  ADD(gsl_rng_xoshiro256_ss);
+  ADD(gsl_rng_xoshiro256_p);
   ADD(0);
 
   return gsl_rng_generator_types;
diff --git rng/xoroshiro64bit.c rng/xoroshiro64bit.c
new file mode 100644
index 00000000..86525280
--- /dev/null
+++ rng/xoroshiro64bit.c
@@ -0,0 +1,339 @@
+/*
+ *  rng/xoroshiro64bit.c
+ *  From http://prng.di.unimi.it/
+ *
+ *  Copyright (C) 2018 David Blackman and Sebastiano Vigna, placed into the Public domain.
+ *  Copyright (C) 2020 Reini Urban, GSL packaging
+ *
+ * To the extent possible under law, the authors have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * See <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <gsl/gsl_rng.h>
+
+static inline uint64_t rotl(const uint64_t x, int k) {
+  return (x << k) | (x >> (64 - k));
+}
+
+/*
+ * These are the wrappers for the xoroshiro128 64bit prngs
+ */
+#define RNG_WRAP(n) \
+  static unsigned long int n##_get (void *vstate);       \
+  static double n##_get_double (void *vstate)
+
+// 64bit
+RNG_WRAP (xoroshiro128_pp);
+RNG_WRAP (xoroshiro128_ss);
+RNG_WRAP (xoroshiro128_p);
+RNG_WRAP (xoshiro256_pp);
+RNG_WRAP (xoshiro256_ss);
+RNG_WRAP (xoshiro256_p);
+static void xoroshiro64_set (void *vstate, unsigned long int s);
+
+typedef struct
+  {
+    uint64_t s[4];
+  }
+xoshiro64_state_t;
+
+/* This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
+   small-state generators. It is extremely (sub-ns) fast and it passes all
+   tests we are aware of, but its state space is large enough only for
+   mild parallelism.
+
+   For generating just floating-point numbers, xoroshiro128+ is even
+   faster (but it has a very mild bias, see notes in the comments).
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+static inline unsigned long int
+xoroshiro128_pp_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t s0 = s[0];
+  uint64_t s1 = s[1];
+  const uint64_t result = rotl(s0 + s1, 17) + s0;
+
+  s1 ^= s0;
+  s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
+  s[1] = rotl(s1, 28); // c
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoroshiro128** 1.0, one of our all-purpose, rock-solid,
+   small-state generators. It is extremely (sub-ns) fast and it passes all
+   tests we are aware of, but its state space is large enough only for
+   mild parallelism.
+
+   For generating just floating-point numbers, xoroshiro128+ is even
+   faster (but it has a very mild bias, see notes in the comments).
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+static inline unsigned long int
+xoroshiro128_ss_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t s0 = s[0];
+  uint64_t s1 = s[1];
+  const uint64_t result = rotl(s0 * 5, 7) * 9;
+
+  s1 ^= s0;
+  s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
+  s[1] = rotl(s1, 37); // c
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
+   for floating-point numbers. We suggest to use its upper bits for
+   floating-point generation, as it is slightly faster than
+   xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
+   except for the four lower bits, which might fail linearity tests (and
+   just those), so if low linear complexity is not considered an issue (as
+   it is usually the case) it can be used to generate 64-bit outputs, too;
+   moreover, this generator has a very mild Hamming-weight dependency
+   making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
+   output; we believe this slight bias cannot affect any application. If
+   you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
+
+   We suggest to use a sign test to extract a random Boolean value, and
+   right shifts to extract subsets of bits.
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s.
+
+   NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
+   better results in our test than the 2016 version (a=55, b=14, c=36).
+*/
+static inline unsigned long int
+xoroshiro128_p_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t s0 = s[0];
+  uint64_t s1 = s[1];
+  const uint64_t result = s0 + s1;
+
+  s1 ^= s0;
+  //s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
+  //s[1] = rotl(s1, 36); // c
+  s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
+  s[1] = rotl(s1, 37); // c
+
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
+   It has excellent (sub-ns) speed, a state (256 bits) that is large
+   enough for any parallel application, and it passes all tests we are
+   aware of.
+
+   For generating just floating-point numbers, xoshiro256+ is even faster.
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+static inline unsigned long int
+xoshiro256_pp_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t result = rotl(s[0] + s[3], 23) + s[0];
+
+  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] = rotl(s[3], 45);
+  #undef s
+  return (unsigned long int)result;
+}
+/* This is xoshiro256** 1.0, one of our all-purpose, rock-solid
+   generators. It has excellent (sub-ns) speed, a state (256 bits) that is
+   large enough for any parallel application, and it passes all tests we
+   are aware of.
+
+   For generating just floating-point numbers, xoshiro256+ is even faster.
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+static inline unsigned long int
+xoshiro256_ss_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t result = rotl(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] = rotl(s[3], 45);
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoshiro256+ 1.0, our best and fastest generator for floating-point
+   numbers. We suggest to use its upper bits for floating-point
+   generation, as it is slightly faster than xoshiro256++/xoshiro256**. It
+   passes all tests we are aware of except for the lowest three bits,
+   which might fail linearity tests (and just those), so if low linear
+   complexity is not considered an issue (as it is usually the case) it
+   can be used to generate 64-bit outputs, too.
+
+   We suggest to use a sign test to extract a random Boolean value, and
+   right shifts to extract subsets of bits.
+
+   The state must be seeded so that it is not everywhere zero. If you have
+   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
+   output to fill s. */
+static inline unsigned long int
+xoshiro256_p_get (void *vstate)
+{
+  #define s state->s
+  xoshiro64_state_t *state = (xoshiro64_state_t*)vstate;
+  const uint64_t result = s[0] + s[3];
+
+  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] = rotl(s[3], 45);
+  #undef s
+  return (unsigned long int)result;
+}
+
+#define TO_DOUBLE(x)  ((x) >> 11) * 0x1.0p-53
+
+static double
+xoroshiro128_pp_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoroshiro128_pp_get(vstate));
+}
+static double
+xoroshiro128_ss_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoroshiro128_ss_get(vstate));
+}
+static double
+xoroshiro128_p_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoroshiro128_p_get(vstate));
+}
+static double
+xoshiro256_pp_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoshiro256_pp_get(vstate));
+}
+static double
+xoshiro256_ss_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoshiro256_ss_get(vstate));
+}
+static double
+xoshiro256_p_get_double (void *vstate)
+{
+  return TO_DOUBLE(xoshiro256_p_get(vstate));
+}
+
+static void xoroshiro64_set (void *vstate, unsigned long int s) {
+
+ /* Initialize automaton using specified seed. */
+ xoshiro64_state_t *state = (xoshiro64_state_t *) vstate;
+ state->s[0] = s;
+ state->s[1] = (s + 1) ^ rotl(s, 8);
+ state->s[2] = (s + 2) ^ rotl(s, 16);
+ state->s[3] = (s + 3) ^ rotl(s, 24);
+}
+
+static const gsl_rng_type xoroshiro128_pp_type =
+{"xoroshiro128++",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoroshiro128_pp_get,
+ &xoroshiro128_pp_get_double};
+
+static const gsl_rng_type xoroshiro128_ss_type =
+{"xoroshiro128**",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoroshiro128_ss_get,
+ &xoroshiro128_ss_get_double};
+
+static const gsl_rng_type xoroshiro128_p_type =
+{"xoroshiro128+",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoroshiro128_p_get,
+ &xoroshiro128_p_get_double};
+
+static const gsl_rng_type xoshiro256_pp_type =
+{"xoshiro256++",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoshiro256_pp_get,
+ &xoshiro256_pp_get_double};
+
+static const gsl_rng_type xoshiro256_ss_type =
+{"xoshiro256**",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoshiro256_ss_get,
+ &xoshiro256_ss_get_double};
+
+static const gsl_rng_type xoshiro256_p_type =
+{"xoshiro256+",                      /* name */
+ UINT64_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro64_state_t),
+ &xoroshiro64_set,
+ &xoshiro256_p_get,
+ &xoshiro256_p_get_double};
+
+const gsl_rng_type *gsl_rng_xoroshiro128_pp = &xoroshiro128_pp_type;
+const gsl_rng_type *gsl_rng_xoroshiro128_ss = &xoroshiro128_ss_type;
+const gsl_rng_type *gsl_rng_xoroshiro128_p  = &xoroshiro128_p_type;
+const gsl_rng_type *gsl_rng_xoshiro256_pp = &xoshiro256_pp_type;
+const gsl_rng_type *gsl_rng_xoshiro256_ss = &xoshiro256_ss_type;
+const gsl_rng_type *gsl_rng_xoshiro256_p  = &xoshiro256_p_type;
diff --git rng/xoshiro32bit.c rng/xoshiro32bit.c
new file mode 100644
index 00000000..dc1edb68
--- /dev/null
+++ rng/xoshiro32bit.c
@@ -0,0 +1,276 @@
+/*
+ *  rng/xoshiro32bit.c
+ *  From http://prng.di.unimi.it/
+ *
+ *  Copyright (C) 2018 David Blackman and Sebastiano Vigna, placed into the Public domain.
+ *  Copyright (C) 2020 Reini Urban, GSL packaging
+ *
+ * To the extent possible under law, the authors have dedicated all copyright
+ * and related and neighboring rights to this software to the public domain
+ * worldwide. This software is distributed without any warranty.
+ *
+ * See <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <gsl/gsl_rng.h>
+
+static inline uint32_t rotl(const uint32_t x, int k) {
+  return (x << k) | (x >> (32 - k));
+}
+
+/*
+ * These are the wrappers for the xoshiro128 32bit prngs
+ */
+#define RNG_WRAP(n) \
+  static unsigned long int n##_get (void *vstate);       \
+  static double n##_get_double (void *vstate)
+
+// 32bit
+RNG_WRAP (xoshiro128_pp);
+RNG_WRAP (xoshiro128_ss);
+RNG_WRAP (xoshiro128_p);
+RNG_WRAP (xoroshiro64_ss);
+RNG_WRAP (xoroshiro64_s);
+static void xoshiro32_set (void *vstate, unsigned long int s);
+
+typedef struct
+  {
+    uint32_t s[4];
+  }
+xoshiro32_state_t;
+
+/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
+   generators. It has excellent speed, a state size (128 bits) that is
+   large enough for mild parallelism, and it passes all tests we are aware
+   of.
+
+   For generating just single-precision (i.e., 32-bit) floating-point
+   numbers, xoshiro128+ is even faster.
+
+   The state must be seeded so that it is not everywhere zero. */
+static inline unsigned long int
+xoshiro128_pp_get (void *vstate)
+{
+  #define s state->s
+  xoshiro32_state_t *state = (xoshiro32_state_t*)vstate;
+  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);
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
+   generators. It has excellent speed, a state size (128 bits) that is
+   large enough for mild parallelism, and it passes all tests we are aware
+   of.
+
+   Note that version 1.0 had mistakenly s[0] instead of s[1] as state
+   word passed to the scrambler.
+
+   For generating just single-precision (i.e., 32-bit) floating-point
+   numbers, xoshiro128+ is even faster.
+
+   The state must be seeded so that it is not everywhere zero. */
+static inline unsigned long int
+xoshiro128_ss_get (void *vstate)
+{
+  #define s state->s
+  xoshiro32_state_t *state = (xoshiro32_state_t*)vstate;
+  const uint32_t result = rotl(s[1] * 5, 7) * 9;
+  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);
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoshiro128+ 1.0, our best and fastest 32-bit generator for 32-bit
+   floating-point numbers. We suggest to use its upper bits for
+   floating-point generation, as it is slightly faster than xoshiro128**.
+   It passes all tests we are aware of except for
+   linearity tests, as the lowest four bits have low linear complexity, so
+   if low linear complexity is not considered an issue (as it is usually
+   the case) it can be used to generate 32-bit outputs, too.
+
+   We suggest to use a sign test to extract a random Boolean value, and
+   right shifts to extract subsets of bits.
+
+   The state must be seeded so that it is not everywhere zero. */
+static inline unsigned long int
+xoshiro128_p_get (void *vstate)
+{
+  #define s state->s
+  xoshiro32_state_t *state = (xoshiro32_state_t*)vstate;
+  const uint32_t result = s[0] + s[3];
+  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);
+  #undef s
+  return (unsigned long int)result;
+}
+
+/* This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
+   generator for 32-bit floating-point numbers. We suggest to use its
+   upper bits for floating-point generation, as it is slightly faster than
+   xoroshiro64**. It passes all tests we are aware of except for linearity
+   tests, as the lowest six bits have low linear complexity, so if low
+   linear complexity is not considered an issue (as it is usually the
+   case) it can be used to generate 32-bit outputs, too.
+
+   We suggest to use a sign test to extract a random Boolean value, and
+   right shifts to extract subsets of bits.
+
+   The state must be seeded so that it is not everywhere zero. */
+static inline unsigned long int
+xoroshiro64_s_get (void *vstate)
+{
+  #define s state->s
+  xoshiro32_state_t *state = (xoshiro32_state_t*)vstate;
+  const uint32_t s0 = s[0];
+  uint32_t s1 = s[1];
+  const uint32_t result = s0 * 0x9E3779BB;
+
+  s1 ^= s0;
+  s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
+  s[1] = rotl(s1, 13); // c
+  #undef s
+  return result;
+}
+
+/* This is xoroshiro64** 1.0, our 32-bit all-purpose, rock-solid,
+   small-state generator. It is extremely fast and it passes all tests we
+   are aware of, but its state space is not large enough for any parallel
+   application.
+
+   For generating just single-precision (i.e., 32-bit) floating-point
+   numbers, xoroshiro64* is even faster.
+
+   The state must be seeded so that it is not everywhere zero. */
+static inline unsigned long int
+xoroshiro64_ss_get (void *vstate)
+{
+  #define s state->s
+  xoshiro32_state_t *state = (xoshiro32_state_t*)vstate;
+  const uint32_t s0 = s[0];
+  uint32_t s1 = s[1];
+  const uint32_t result = rotl(s0 * 0x9E3779BB, 5) * 5;
+
+  s1 ^= s0;
+  s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
+  s[1] = rotl(s1, 13); // c
+  #undef s
+  return result;
+}
+
+static double
+xoshiro128_pp_get_double (void *vstate)
+{
+  return xoshiro128_pp_get(vstate) / (double) UINT32_MAX;
+}
+static double
+xoshiro128_ss_get_double (void *vstate)
+{
+  return xoshiro128_ss_get(vstate) / (double) UINT32_MAX;
+}
+static double
+xoshiro128_p_get_double (void *vstate)
+{
+  return xoshiro128_p_get(vstate) / (double) UINT32_MAX;
+}
+static double
+xoroshiro64_ss_get_double (void *vstate)
+{
+  return xoroshiro64_ss_get(vstate) / (double) UINT32_MAX;
+}
+static double
+xoroshiro64_s_get_double (void *vstate)
+{
+  return xoroshiro64_s_get(vstate) / (double) UINT32_MAX;
+}
+
+static void xoshiro32_set (void *vstate, unsigned long int s) {
+
+ /* Initialize automaton using specified seed. */
+ xoshiro32_state_t *state = (xoshiro32_state_t *) vstate;
+ state->s[0] = s;
+ state->s[1] = (s + 1) ^ rotl(s, 8);
+ state->s[2] = (s + 2) ^ rotl(s, 16);
+ state->s[3] = (s + 3) ^ rotl(s, 24);
+}
+
+static const gsl_rng_type xoshiro128_pp_type =
+{"xoshiro128++",                      /* name */
+ UINT32_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro32_state_t),
+ &xoshiro32_set,
+ &xoshiro128_pp_get,
+ &xoshiro128_pp_get_double};
+
+static const gsl_rng_type xoshiro128_ss_type =
+{"xoshiro128**",                      /* name */
+ UINT32_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro32_state_t),
+ &xoshiro32_set,
+ &xoshiro128_ss_get,
+ &xoshiro128_ss_get_double};
+
+static const gsl_rng_type xoshiro128_p_type =
+{"xoshiro128+",                      /* name */
+ UINT32_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro32_state_t),
+ &xoshiro32_set,
+ &xoshiro128_p_get,
+ &xoshiro128_p_get_double};
+
+static const gsl_rng_type xoroshiro64_ss_type =
+{"xoroshiro64**",                      /* name */
+ UINT32_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro32_state_t),
+ &xoshiro32_set,
+ &xoroshiro64_ss_get,
+ &xoroshiro64_ss_get_double};
+
+static const gsl_rng_type xoroshiro64_s_type =
+{"xoroshiro64*",                      /* name */
+ UINT32_MAX,			/* RAND_MAX */
+ 0,				/* RAND_MIN */
+ sizeof (xoshiro32_state_t),
+ &xoshiro32_set,
+ &xoroshiro64_s_get,
+ &xoroshiro64_s_get_double};
+
+const gsl_rng_type *gsl_rng_xoshiro128_pp = &xoshiro128_pp_type;
+const gsl_rng_type *gsl_rng_xoshiro128_ss = &xoshiro128_ss_type;
+const gsl_rng_type *gsl_rng_xoshiro128_p  = &xoshiro128_p_type;
+const gsl_rng_type *gsl_rng_xoroshiro64_ss = &xoroshiro64_ss_type;
+const gsl_rng_type *gsl_rng_xoroshiro64_s  = &xoroshiro64_s_type;
-- 
2.26.2

Reply via email to