A Tausworthe random number generator

monarch_dodra monarchdodra at gmail.com
Wed Jan 22 03:02:08 PST 2014


On Wednesday, 22 January 2014 at 09:33:39 UTC, terchestor wrote:
> My problem is the cast to integral type (line 80), downgrading 
> performances of circa 50%.
> Is there any possibility to avoid it?

I'd say it's your "Tconst_tau0" that is getting in your way: You 
have a uint sized integral, which you divide by a floating point, 
just to multiply it again and cast back to integral type (!).

I'd suggest you get rid of "high/low" completly. There are prng 
*adaptors* that can create a uniform distribution *from* a 
natural prng (std.random.uniform). If you do this, you code 
becomes (starting line 73):

         auto uni = (s1 ^ s2 ^ s3);
         static if (isFloatingPoint!result_t)
         {
             return uni / Tconst_tau0;
         }
         else
         {
             return uni;
         }

Heck, you could get rid of floating point support entirely, and 
generate only integrals. Then, you just let "uniform" do the 
tough work:

auto rnd = tausworthe!(ulong, uint)(randomSeed);

auto rndF    = rnd.uniform!"[)"(0.0,  1.0); //0 - 1 double range
auto rnd1024 = rnd.uniform!"[)"(0,   1024); //[0 .. 1024) 
integral range.

Nitpick:
         /// get seed from current time
         auto se = Clock.currTime().stdTime;

This is known to be a bad seed. If you need a "good enough" seed, 
use "std.random.randomSeed". Although arguably (IMO), it is 
better place the burden of seeding on the caller.


More information about the Digitalmars-d mailing list