15 November 2020, 15:24 | #1 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
Random numbers
I was looking for some algorithm how to create random numbers. When I look at the glibc source, it looks extremly complicated and expensive. Another approach I became aware of was, to use a Murmur2 hash value. This works quite nice, but it also looks computationally expensive. From guts feeling I think it's not as expensive as the glibc code, but still. So I was wondering if there is some better approach which is also fast.
At least the Murmur2 code looks much easier to translate to asm, so if there is no better alternative I will take that one. As a nice side effect, I have then a hashing algorithm as well. |
15 November 2020, 16:11 | #2 |
Registered User
Join Date: Oct 2009
Location: Germany
Posts: 3,311
|
If you search the Coders forum for "random" you get some threads that should give several solutions for fast and cheap random generators. There is also a long discussion I remember with code examples.
|
15 November 2020, 16:15 | #3 |
Registered User
Join Date: Jan 2002
Location: Germany
Posts: 7,035
|
I once looked at the algorithm used by C64 Basic. It's really simple: it takes the 32bit seed, EORs it by a large random number (probably a prime number) and orders the bytes backward.
The seed was then interpreted as a float and normalized to be between 0 and 1. But that's not necessary, you already get quite good results if you divide the seed by the desired range and use the remainder as result. Something like this for random numbers between 1 and 6: Code:
move.l seed,d0 eor.l #$87654321,d0 swap.w d0 swap.l d0 swap.w d0 move.l d0,seed divu #6,d0 swap.l d0 ext.l d0 addq.l #1,d0 |
15 November 2020, 16:22 | #4 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
Thanks. I tried to search, but I didn't find much. Maybe the wrong search phrase.
That algorithm looks nice and simple. |
15 November 2020, 16:54 | #5 |
This cat is no more
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,388
|
Code:
;;; EAB simple random generator ; thanks meynaf mulu #$a57b,d0 addi.l #$bb40e62d,d0 rol.l #6,d0 |
15 November 2020, 19:09 | #6 |
Moderator
Join Date: Nov 2001
Location: Germany
Posts: 876
|
Code:
move.l seed,d0 eor.l #$87654321,d0 swap.w d0 swap.l d0 swap.w d0 move.l d0,seed divu #6,d0 swap.l d0 ext.l d0 addq.l #1,d0 there is only swap |
15 November 2020, 20:39 | #7 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,331
|
Donald Knuth, "The Art of Programming", Vol. II: "Numerical and Semi-numerical algorithms". Contains everything you ever wanted to know about random generators and you never dared to ask.
The quick morale: Do not pick the algorithm to generate random numbers at random. In particular, do not accept "home made" algorithms. About the simplest random number generators are "linear congruence random generators", which use a multiply-add approach. Depending on the numbers you pick, the results are "ok". Quote:
Code:
saveregs a2/a6 lea _Seed(a4),a2 move.l (a2),d0 move.l _UtilityBase(a4),a6 move.l #1664525,d1 ;Knuth's algorithm jsr -$90(a6) ;UMul add.l #1013904223,d0 move.l d0,(a2) loadregs rts This is Knuth's linear congruence algorithm with a modulo value of 2^32. It is well researched and well understood. Do not exchange the multiplication with anything else, neither its constant. Note that if you use the output of this algorithm: Always use data from the MSBs on, do not generate random numbers by "masking", as the LSBs have a much smaller period. |
|
15 November 2020, 22:10 | #8 | |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
Quote:
This will not, however, fix the problem with the short period of the algorithm (for a 32-bit seed, it's in the thousands). |
|
16 November 2020, 09:06 | #9 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,068
|
1. short
2. fast 3. accurate Pick two :P. This is a quick&dirty one that works for me: Code:
Init: move.l #<seed>,d7 ; large prime numbers move.l #$6be7d35b,d6 ; are good... Rng: swap d7 add.l d6,d7 eor.l d6,d7 |
16 November 2020, 09:49 | #10 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,331
|
No. The period of a linear congruence random generator does not depend on the seed. It depends on the gcd of the modulo and the multiplier, here 2^32 and, well, the magic number in the code. This number here was not picked at random, so the period is really maximal. It is not in the thousands. Note, however, that this assumes that you pick bits from the MSB on. The period on the LSBs is small.
|
16 November 2020, 09:50 | #11 | |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,331
|
Quote:
|
|
16 November 2020, 10:05 | #12 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,068
|
The one I posted? That one, as stated, works for me, to generate a few thousand random 16-bit numbers very quickly (6 bytes inline, 20 cycles on a 68000).
Xorshift? Yeah, there are many variants that pass the bigcrush tests. Look up xorshift and xoshiro. But most importantly, read the first 4 lines (and pick two) :P. That's the point. |
16 November 2020, 10:45 | #13 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,331
|
The question is not "whether it works for you", but whether it is a good random generator and passes a couple of tests, for example the spectral test. See again Knuth II for a lot of tests and a lot of material on random generators, and in particular why home-made generators are not a good idea.
|
16 November 2020, 11:22 | #14 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,068
|
moveq #oh-how-i-love-arguing-with-internet-strangers-about-nothing,d0
... not.l d0 Again, you are missing the point. Taking a step back, xorshift is not some mumbo jumbo, and as i said it passes the bigcrush test which is a few hours long test. Now, back to code I posted... You should stop looking at this from your point of view only, especially in a coders/asm forum. - Original poster said, in a general manner, that he needs a fast algorithm but doesn't specify how fast is fast enough for his definition of fast in this fast moving thread. - Apply 2-out-of-3 rule. - Different people present different options. 0-1 choice 0-$ff better choice 0-$ffff betterer choice 0-$ffffffff bettererer choice So what's the problem? Need better accuracy (*again*, 2-out-of-3 rule)? 1. pick a better seed/modifier 2. use shift/ror instead of a swap 3. use 2x32 bits ... 9. use the "full-blown" xorshift algorithm, which is still plenty fast, if you still like this type of rng 10. use something else that you like more or that works better in your, and unknown to us, scenario |
16 November 2020, 11:51 | #15 |
Registered User
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
|
The numbers should be sufficiently random for a game. they don't need to hold against a scientific test. So in a game, speed is important, but I think if I have the choice between a bad generator and a little bit slower one, then I might take the slower one. If it starts to get a performance issue, then a less "random" algorithm might be acceptable. I thought of adding a few of them and then compare how the perform vs. how they "feel" regarding randomness.
|
16 November 2020, 14:38 | #16 | |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
Quote:
|
|
16 November 2020, 14:45 | #17 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,365
|
Indeed xorshift is fast and passes many tests (not all : it fails linear complexity tests). While unsuitable for cryptography, for most applications it's more than enough.
|
16 November 2020, 15:40 | #18 |
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,331
|
I don't see how one contradicts the other. Depending on the type of game, and your needs for randomness, a good generator is absolutely necessary, and not a "scientific exercise" at all. Without knowing the game and your needs, one cannot give recommendations.
|
16 November 2020, 16:25 | #20 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,438
|
Now I've been looking for a random number algorithm generator as well and it looks like something like xorshift would be good enough for my purpose. Assuming I'd use xorshift, what would be good initial seed (or state) values for 32 bit signed/unsiged random numbers?
See, to me it seems to me that getting the seed right is the critical part for using this type of algorithm properly. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Serial Numbers vs QC numbers question | 005AGIMA | support.Other | 1 | 05 January 2020 13:53 |
Fast floating-point random numbers | Leffmann | Coders. Tutorials | 27 | 25 August 2016 01:59 |
Help needed!!Random octal numbers generator(asm) | sheryn88 | Coders. General | 6 | 01 August 2010 07:19 |
A nice quick small random numbers routine? | Photon | Coders. General | 2 | 20 December 2004 21:56 |
IP numbers | Squonk | project.WinUAE - Kaillera | 0 | 24 September 2003 13:12 |
|
|