MKoD - D Programming Language

ISAAC a 32-bit general purpose pseudo-random number generator - code-name isaac.d

Very Kool! Pseudo-random number generator example:

/+
 ' ISAAC, a 32-bit general purpose pseudo-random number generator.
 ' (c) By Bob Jenkins, March 1996, Public Domain
 '
 ' You may use this code in any way you wish, and it is free. No warrantee.
 ' ------------------------------------------------------------------------
 ' Original "C" code can be found at: 
 ' http://www.burtleburtle.net/bob/rand/isaacafa.html
 '
 ' Converted to "D" by David L. 'SpottedTiger' Davis
 ' To Compile: C:\dmd\MKoD_ex>dmd isaac.d
 '
 ' 02.Oct.04 Compiled and Tested with dmd v0.102
 ' 04.Jun.06 Compiled and Tested with dmd v0.160
 ' 10.Jan.07 Compiled and Tested with dmd v1.0
 '
 +/

private import std.stdio;

//typedef uint ub4;   

/+
 ' Using D's uint because we need a value that's in unsigned 4-byte quantities 
 '
 +/
 
// * external results *
uint[ 256 ] randrsl;
uint        randcnt;

// * internal state *
static uint[ 256 ] mm;
static uint aa = 0;
static uint bb = 0;
static uint cc = 0;

void isaac()
{
   uint i;
   uint x;
   uint y;

   cc = cc + 1;    // * cc just gets incremented once per 256 results *
   bb = bb + cc;   // * then combined with bb *

   for( i = 0; i < 256; ++i )
   {
     x = mm[ i ];
     
     switch( i % 4 )
     {
       case 0: aa = cast(uint)aa^( aa << 13 ); break;
       case 1: aa = cast(uint)aa^( aa >>  6 ); break;
       case 2: aa = cast(uint)aa^( aa <<  2 ); break;
       case 3: aa = cast(uint)aa^( aa >> 16 ); break;
       default:
     }
     
     aa           = mm[ ( i + 128 ) % 256 ] + aa;
     y            = mm[ ( x >> 2 ) % 256 ] + aa + bb;
     mm[ i ]      = y;
     bb           = mm[ ( y >> 10 ) % 256 ] + x;
     randrsl[ i ] = bb;

   }
} // end void isaac()

void randinit
( 
    in bool flag
)
{
   uint i;
   uint a;
   uint b;
   uint c;
   uint d;
   uint e;
   uint f;
   uint g;
   uint h;
   uint *m;
   uint *r;
   
   aa = 0;
   bb = 0; 
   cc = 0;
   
   // * the golden ratio *
   a = 0x9e3779b9;
   b = 0x9e3779b9;
   c = 0x9e3779b9;
   d = 0x9e3779b9;
   e = 0x9e3779b9;
   f = 0x9e3779b9;
   g = 0x9e3779b9;
   h = 0x9e3779b9;  
   
   // * scramble it *
   for( i = 0; i < 4; ++i )  
   {
     mix( a, b, c, d, e, f, g, h );
   }
   
   // * fill in mm[] with messy stuff *
   for( i = 0; i < 256; i += 8 ) 
   {
     if( flag )                  
     {
       // * use all the information in the seed *
       a += randrsl[ i     ]; b += randrsl[ i + 1 ]; 
       c += randrsl[ i + 2 ]; d += randrsl[ i + 3 ];
       e += randrsl[ i + 4 ]; f += randrsl[ i + 5 ]; 
       g += randrsl[ i + 6 ]; h += randrsl[ i + 7 ];
     }
     
     mix( a, b, c, d, e, f, g, h );
     mm[i      ] = a; mm[ i + 1 ] = b; 
     mm[ i + 2 ] = c; mm[ i + 3 ] = d;
     mm[ i + 4 ] = e; mm[ i + 5 ] = f; 
     mm[ i + 6 ] = g; mm[ i + 7 ] = h;
   }

   if( flag )
   {        
     // * do a second pass to make all of the seed affect all of mm *
     for( i = 0; i < 256; i += 8 )
     {
       a += mm[ i     ]; b += mm[ i + 1 ]; 
       c += mm[ i + 2 ]; d += mm[ i + 3 ];
       e += mm[ i + 4 ]; f += mm[ i + 5 ]; 
       g += mm[ i + 6 ]; h += mm[ i + 7 ];
       
       mix( a, b, c, d, e, f, g, h );
       mm[ i     ] = a; mm[ i + 1 ] = b; 
       mm[ i + 2 ] = c; mm[ i + 3 ] = d;
       mm[ i + 4 ] = e; mm[ i + 5 ] = f; 
       mm[ i + 6 ] = g; mm[ i + 7 ] = h;
     }
   }

   // * fill in the first set of results *
   isaac();        
   
   // * prepare to use the first set of results *
   randcnt = 256;  
   
} // end void randinit( in bool )

void mix
(
    inout uint a,
    inout uint b,
    inout uint c,
    inout uint d,
    inout uint e,
    inout uint f,
    inout uint g,
    inout uint h
)
{ 
   a ^= b << 11; d += a; b += c; 
   b ^= c >>  2; e += b; c += d; 
   c ^= d <<  8; f += c; d += e; 
   d ^= e >> 16; g += d; e += f; 
   e ^= f << 10; h += e; f += g; 
   f ^= g >>  4; a += f; g += h; 
   g ^= h <<  8; b += g; h += a; 
   h ^= a >>  9; c += h; a += b; 
   
} // end void mix( inout uint, inout uint, inout uint, inout uint, inout uint, inout uint, inout uint, inout uint )

int main()
{
  uint i;
  uint j;
  
  aa = 0;
  bb = 0;
  cc = 0;
  
  for( i = 0; i < 256; ++i ) mm[ i ] = randrsl[ i ] = 0;
  
  randinit( true );
  
  for( i = 0; i < 2; ++i )
  {
    isaac();
    
    for( j = 0; j < 256; ++j )
    {
      writefln( "%08X", cast(uint)randrsl[ j ] );
      if( ( j & 7 ) == 7 ) writefln();
    }
  }
  
  return 0;
  
} // end main()

C:\dmd\MKoD_ex>..\bin\dmd isaac.d
C:\dmd\bin\..\..\dm\bin\link.exe isaac,,,user32+kernel32/noi;

 ...
 
75C08A36
18C1EF9A
D649A428
C5B71937
8A30738A
D97CD348
858129A6
239E3B0A

BBB8ABC4
80FAC4C2
ECFCF20B
D9D711F9
E2A4EF71
B5FE87C0
BE8B06B2
AAFEF5A7

9C15DB3B
0AEB8165
4389A84A
253B1D7A
19047C79
7CDC78A2
D20ADF03
56F55A71

3E730FA8
FD8650D8
959E234E
B7546681
DAD1B22A
142A6E85
8EF4BCE6
68235B9D

85A13F85
74096AE7
A949BEA2
29322D0D
D5683858
82846526
403DAE08
6DD1943A

E1279BFF
9E7E4F04
1C3A4524
484525E4
81D4CC5F
E24124C0
037464C0
BF1BD691

26CEB003
275EAD3A
C5BDE908
26414FF3
A30519AD
D7B43ABE
2CE5D3D5
88412761

 ...

C:\dmd\MKoD_ex>
Mars: fourth Rock from the Sun.