For “NON-GAMING PURPOSES ONLY”. In a moment of work avoidance I added a Weyl generator to the above (making it an XorWOW) and ran it through Crush. It passes all test. As a point of reference, the famous Mersenne twister (on it’s own) will fail 2.
I have no idea why the over rated, slow and quite poor MT is so popular. It doesn’t even fix the problem it was suppose to solve. That is the hyperplanes problem, it just has a lot of them. Weyl generator + m sequence, done. Faster, no hyperplanes and great for serious random number. The only thing you shouldn’t use it for is crypto stuff.
I think it’s because it has the one of most cool names is about the only reason. I want to cry every time I see a game using MT. I slowly working on a runtime game PRNG wiki page so HOPEFULLY nobody here will fall into that trap.
Over there is a XOR-shift generator mentioned, which seems to perform well on test suites:
http://www.javamex.com/tutorials/random_numbers/xorshift.shtml
[quote]The “magic” values of 21, 35 and 4 have been found to produce good results. With these values, the generator has a full period of 264-1, and the resulting values pass Marsaglia’s “Diehard battery” of statistical tests for randomness4. L’Ecuyer & Simard (2007)5 also found that values of 13, 7 and 17 fail on only 7 of the 160 tests of their BigCrush battery (for comparison, java.util.Random fails on 21, while crypographic generators such as Java’s SecureRandom— as indeed we might expect— generally pass all tests).
[/quote]
Remember that all of this statistical testing is a tangent and is of about zero interest for a game runtime. Quickly tossing the [21,35,4] numbers in (without a Weyl) and it fails 2 SmallCrush tests where the current [13,7,17] only fails one.
Hehe: “A man is only as interesting as his contradicts”.
Seriously, I understand were you’re coming from. That’s why I’m doing a first pass at a wiki page.
The problems with java.util.Random isn’t one of quality. The quality of its generator is poor, but it is perfectly adequate for virtually all game runtime usage. I most often use a LCG32 which is poorer quality…but it’s sufficient most of the time. It’s the design of Random that’s the problem…it doesn’t properly target any specific use-case. You can get sufficient quality much faster and even vastly superior quality faster. So the bottom line is that you’re paying a higher than needed cost. If you don’t generate many random numbers then it’s not really a concern. (I’m ignoring dimensions here)
On the topic of quality, the only reason to consider it here is the notion of maximizing what you get for a given fixed cost. Even if that is only addressing programmer conform-zone issues…it’s for “free” so why not choose the known constants that perform the best.
WRT: The link you provided. The thing is there are thousands of 64-bit xorshift and I “know” that none of them alone will pass Crush or BigCrush. No LSFR random number generator will (including MT). DIEHARD (the quoted test) is dated and SmallCrush contains the same tests. It fails SmallCrush simply because that test-suite has been updated to require more computations per test than DIEHARD.
Does that at least partially clarify?
I think this was a reply to the message which I deleted soon after posting it. Soon after posting it appeard to me that it isn’t of general interest and that I don’t want to stir up more discussion, so I deemed me better to delete it. Sorry for writing it in the first place. Random numbers are a wide field, require in depth math and computational science knowledge and I assume my own level in those domains is about as good to decide which RNG is good for my purpose, or to see if code is efficient. So I want to leave the expert discussion to you and those who know more. For myself I conclude:
- Random() is usually good enough for me needs (i.e. I made no mistakes in my past projects, that need to be fixed).
- I used mersenne twister in my C/C++ programs and learned that it is inefficient, but most likely still good enough.
- My choice to use SecureRandom() for high quality random numbers in Solarex was right, since performance isn’t an issue there, but the quality of the number sequence is.
- Xor-Shift is an interesting method which I didn’t know before, since it’s fast and passes standard tests (i.e. it doesn’t have any obvious fails)
… and more I don’t need to know for my projects. Sorry for stirring up more discussion than needed
For the record and for completeness. Using a xor shift scheme with the correct constants produces m-sequences. These have clearly defined randomness properties. They are heavily used for testing binary circuits and for communications etc. They have nice mathematics behind them and have all sorts of properties that make them useful for many things.
In short we know a lot about them.
However random here is typically defined as the Spectrum it produces should be white (or the autocorrelation function should be a Dirac delta). Alternatively an 8 bit register will produce every 8 bit number once and only once except 0. Clearly this is not true random. For somethings this is good. For example with stochastic integration you get faster convergence because successive numbers clump less than true random.
If non of that matters to you, then a simple m-sequence generator is perhaps going to be the easiest and fastest by a long shot.
For the few of us doing some scientific simulations, we perhaps want to break up some of the m-sequence structure. This is most easily done with a the previously mentioned weyl generator and then add the results together. This gives nonliterary and passes every test (or not) the same as true random. It is also just 2 extra additions compared to a m-sequences. It is often even faster than LGC because % tends to be pretty slow.
For crypto… well stop reading here for start. Your doing it wrong.