Pseudo-random Number Generator

From Second Life Wiki
Revision as of 07:32, 2 October 2007 by Ppaatt Lynagh (talk | contribs) (suggest yyyymmddnn test seeds)
Jump to navigation Jump to search

Heres a Pseudo-random Number Generator - I just made it up off the top of my head - so it has no mathematical research behind it to prove it's random... I've tested it for a while and it looks random to me, about the same as llFrand(). The main reason that I use it so that I can test scripts, and then when it blows up because of a math error or something I can just run the script again an it will use the same numbers, in the same order. It can also be used for two (or more) scripts to talk on a more-or-less channel. But what ever. Sue me.

I use this for determining a random channel for two (or more) objects to talk on. This allows the scripts to talk without users being able to intercept the messages - and even if they do - then the channel will change in a minute or two - so no harm done.

I recently compared this with llFrand() and it is on average 5% faster.

Note: A pattern of digits like yyyymmddnn often works as a seed that changes often enough, e.g., test with 2007090103 == 2,007,090,103 as the 3rd try of the 1st day of the 9th month of the 2007th year, except you must take care to avoid confusing yourself with integers larger than the 2,147,483,647 limit of 32-bit signed arithmetic.

// IMPORTANT: Change the following number before using!
integer seed = 0x61FA687C;


integer rand() {
    seed = (integer)(seed * 0x71B5F252 + 0xD);
    return seed ^ 0x7FFFFFFF;
}

Example code to test the randomness (Is that a word?) of the generator.

default {
	state_entry() {
		integer i = 0;
		integer min = 0x7FFFFFFF;
		integer max = -0x7FFFFFFF;
		integer total = 0;
		while (i < 100000000) {
			integer r = rand();
			if (r < min) {
				min = r;
			}
			if (r > max) {
				max = r;
			}
			total += r;
			i++;
		}
		llOwnerSay("Min: " + (string)min);
		llOwnerSay("Max: " + (string)max);
		llOwnerSay("Average: " + (string)(total/100000000));

	}

}