{{ message }}

Instantly share code, notes, and snippets.

# raxoft/xorshift.asm

Created May 22, 2015
Fast quality Xor-Shift random number generator for Z80 I have created to weed out the crap RNGs out there. 28 bytes, 122 T cycles, period 2^32-1.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 ; 8-bit Xor-Shift random number generator. ; Created by Patrik Rak in 2008 and revised in 2011/2012. ; See http://www.worldofspectrum.org/forums/showthread.php?t=23070 org 40000 call rnd ; BASIC driver ld c,a ld b,0 ret rnd ld hl,0xA280 ; yw -> zt ld de,0xC0DE ; xz -> yw ld (rnd+4),hl ; x = y, z = w ld a,l ; w = w ^ ( w << 3 ) add a,a add a,a add a,a xor l ld l,a ld a,d ; t = x ^ (x << 1) add a,a xor d ld h,a rra ; t = t ^ (t >> 1) ^ w xor h xor l ld h,e ; y = z ld l,a ; w = t ld (rnd+1),hl ret

### lab2k1 commented Jun 22, 2017 • edited

Thank you for the code, and the insights in that worldofspectrum thread. I have a couple of questions (apologies in advance if they turn out to be "obvious" but it's been a really long time since I wrote Z80 assembly last, or did any serious math for that matter).

First off, Marsaglia's pseudo-C-code in the Xorshift RNGs paper `t=(xˆ(x<<a)); x=y; y=z; z=w; return w=(wˆ(w>>c))ˆ(tˆ(t>>b));` has the `w` shifted right rather than left. I reckon that it's an entirely different context there vs. the 8-bit case here, yet I was wondering if/how it matters.

Secondly, the code here is using the `(1,1,3)` triplet, but since the first two parameters are numerically equal it is not obvious which is which. Does it follow Marsaglia's notation for `(a,b,c)` where `a` is the shift count for `x`, `b` for `t` and `c` for `w`? Somewhat related, I was wondering how does `slightly better` quantify in this line: `(3,3,2) and (5,3,2) seem to get slightly better results in the Diehard tests`.

### raxoft commented Apr 27, 2018

As shown in the paper, the direction of the shift is your choice. You can choose any of the 8 combinations, and then you look for the triplets for that particular combination. In this case, I wanted 2 left and one right, as shifting left fast is somewhat easier than shifting right.

As for the triplets, yes, it uses the same `(a,b,c)` notation as the paper does. As for slightly better, if you run the Diehard tests, IIRC, those two triples fail few less tests than the (1,1,3). However, it's still far from perfect so it doesn't matter much. This class of generators is bound to fail some of them anyway. If you want/need something really robust in this regard, use my CMWC Z80 generator instead.