Permalink
Browse files

Decreased utils.Random execution time by approximately 70%.

  • Loading branch information...
1 parent 3485b0b commit 1dac03aeedd413da70ac40ec8596ec1311902755 @skyboy committed Feb 7, 2012
Showing with 81 additions and 48 deletions.
  1. +81 −48 skyboy/utils/Random.as
View
@@ -9,8 +9,14 @@ package skyboy.utils {
public static function randomNumber():Number {
return r.extractNumber();
}
- private const MT:Vector.<int> = new Vector.<int>(624);
+ private const MT:Vector.<uint> = new Vector.<uint>(624, true);
private var index:int, _seed:int;
+ private const yA1:uint = 2636928640, yA2:uint = 4022730752;
+ private const a:uint = 2147483648, b:uint = 2147483647, c:uint = 2567483615, d:uint = 624, e:uint = 397;
+ private static const I_MAX:uint = int.MAX_VALUE;
+ private static const U_MAX:uint = uint.MAX_VALUE;
+ private static const iDIV:Number = I_MAX + Number.MIN_VALUE + 1;
+ private static const uDIV:Number = U_MAX + Number.MIN_VALUE;
/**
* Get the seed currently in use
*/
@@ -22,90 +28,117 @@ package skyboy.utils {
*/
public function set seed(a:int):void {
if (a != _seed) {
- var i:int, b:int = MT[index = 0] = _seed = seed;
- while (++i < 624) b = (MT[i] = (1812433253 * b ^ ((b >>> 30) + i)) & 0xFFFFFFFF);
+ _seed = a;
+ var i:int, b:int = a;
+ index = i;
+ MT[i] = a;
+ while (++i < 624) {
+ b = (MT[i] = (1812433253 * Number(b ^ (b >>> 30)) + i) & 0xFFFFFFFF);
+ }
}
}
/**
* @param int: seed The seed number to use, using the same seed will get you the same results each time
*/
public function Random(seed:int):void {
- var i:int, b:int = MT[0] = _seed = seed;
- while (++i < 624) b = (MT[i] = (1812433253 * b ^ ((b >>> 30) + i)) & 0xFFFFFFFF);
+ _seed = seed - 1;
+ this.seed = seed;
}
/**
- * extractNumber
+ * Returns a number that is greater than or equal to zero and less than one
* @return Number: A number that is greater than or equal to zero and less than one
*/
public function extractNumber():Number {
- if (index == 0) generateNumbers();
- var y:int = MT[index];
- index = (index + 1) % 624;
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
y ^= y >>> 11;
- y ^= (y << 7) & 2636928640;
- y ^= (y << 15) & 4022730752;
- return uint(y ^ (y >>> 18)) / (uint.MAX_VALUE + Number.MIN_VALUE);
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
+ y ^= y >>> 18;
+ return y / uDIV;
}
/**
- * extractNumber2
+ * Returns a number that is greater than negative one and less than one
* @return Number: A number that is greater than negative one and less than one
*/
public function extractNumber2():Number {
- if (index == 0) generateNumbers();
- var y:int = MT[index];
- index = (index + 1) % 624;
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
y ^= y >>> 11;
- y ^= (y << 7) & 2636928640;
- y ^= (y << 15) & 4022730752;
- return (y ^ (y >>> 18)) / (int.MAX_VALUE + Number.MIN_VALUE);
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
+ return (y ^ (y >>> 18)) / iDIV;
}
/**
- * extractNumber3
+ * Returns a number that is greater than negative 0.5 and less than 0.5
* @return Number: A number that is greater than negative 0.5 and less than 0.5
*/
public function extractNumber3():Number {
- if (index == 0) generateNumbers();
- var y:int = MT[index];
- index = (index + 1) % 624;
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
y ^= y >>> 11;
- y ^= (y << 7) & 2636928640;
- y ^= (y << 15) & 4022730752;
- return (y ^ (y >>> 18)) / (uint.MAX_VALUE + Number.MIN_VALUE);
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
+ return int(y ^ (y >>> 18)) / uDIV;
}
/**
- * extractUint
+ * Returns an unsigned integer between 0 and uint.MAX_VALUE
* @return uint: An unsigned integer between 0 and uint.MAX_VALUE
*/
public function extractUint():uint {
- if (index == 0) generateNumbers();
- var y:int = MT[index];
- index = (index + 1) % 624;
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
y ^= y >>> 11;
- y ^= (y << 7) & 2636928640;
- y ^= (y << 15) & 4022730752;
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
return (y ^ (y >>> 18));
}
/**
- * extractInt
- * @return int: An integer between int.MIN_VALUE and int.MAX_VALUE
+ * Returns an unsigned integer between min and max
+ * @return uint: An unsigned integer between min and max
*/
- public function extractInt():int {
- if (index == 0) generateNumbers();
- var y:int = MT[index];
- index = (index + 1) % 624;
+ public function extractBoundedUint(min:uint, max:uint):uint {
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
y ^= y >>> 11;
- y ^= (y << 7) & 2636928640;
- y ^= (y << 15) & 4022730752;
- return (y ^ (y >>> 18));
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
+ y ^= y >>> 18;
+ if (max < min) {
+ return (y % (min + 1 - max)) + max;
+ }
+ return (y % (max + 1 - min)) + min;
}
+ /**
+ * extractExperimentalUint
+ * @return int: An unsigned integer between 0 and uint.MAX_VALUE
+ * /
+ public function extractExperimentalUint():uint {
+ var i:int = index, MT:Vector.<uint> = this.MT, y:uint = MT[i];
+ index = (i + 1) % 624;
+ var u:uint = (y & a) | (MT[index] & b);
+ MT[i] = (MT[(i + e) % d] ^ (u >>> 1)) ^ (c & (-(u & 1)));
+ y ^= y >>> 11;
+ y ^= (y << 7) & yA1;
+ y ^= (y << 15) & yA2;
+ return (y ^ (y >>> 18));
+ }//*/
private function generateNumbers():void {
- var i:int, y:int;
- while (i < 623) {
- if ((y = (MT[i] & 2147483648) | (MT[(++i) % 624] & 2147483647)) & 1) {
- MT[i] = (MT[(i + 396) % 624] ^ (y >>> 1)) ^ 2567483615;
- } else {
- MT[i] = MT[(i + 396) % 624] ^ (y >>> 1);
- }
+ var i:int, y:int, MT:Vector.<uint> = this.MT;
+ while (i < 624) {
+ y = (MT[i] & a) | (MT[(i+1) % d] & b);
+ MT[i] = (MT[(i + e) % d] ^ (y >>> 1)) ^ (c & (-(y & 1)));
+ ++i;
}
}
}

0 comments on commit 1dac03a

Please sign in to comment.