Confusion about `Random`

Steven Schveighoffer schveiguy at gmail.com
Fri Dec 23 00:58:01 UTC 2022


On 12/22/22 11:23 AM, jwatson-CO-edu wrote:
> I am confused about why Program 1 produces random output but Program 2 
> does not.
> 
> ---
> 
> ### Program 1
> ```d
> import std.stdio;
> import std.conv;
> import std.random;
> 
> Mt19937 rnd;
> 
> double rand01(){
>      // Uniform random sampling in [0,1)
>      return uniform( 0.0, 1.0, rnd);
> }
> 
> void main(){
>      rnd = Random( unpredictableSeed );
>      for( uint i = 0; i < 6; i++ ){
>          writeln( rand01() );
>      }
> }
> ```
> 
> Output:
> ```
> 0.35332
> 0.0687847
> 0.563096
> 0.37718
> 0.321598
> 0.530525
> ```
> 
> ---
> 
> ### Program 2
> #### sparrow_core.d
> ```d
> // ...
> 
> Mt19937 rnd; // Randomness
> 
> void init_random(){
>      // Seed the RNG with the clock
>      rnd = Random( unpredictableSeed );
> }
> 
> // ...
> 
> double rand01(){
>      // Uniform random sampling in [0,1)
>      return uniform( 0.0, 1.0, rnd);
> }
> 
> // ...
> 
> // Build a dict of primitive symbols
> primitiveSymbols["rand"] = function Atom*(){
>      // Random number on [0,1)
>      return new Atom( rand01() ); // Construct an Atom holding a random 
> value
> };
> 
> // ...
> 
> void init_SPARROW(){
>      // Populate necessary global structures
>      init_reserved(); // - Reserved symbols
>      init_env(); // ------ Global context
>      init_primitives(); // Special atoms and Primitive Functions
>      init_specials(); // - Special forms
>      init_random(); // --- RNG
> }
> ```
> 
> #### app.d
> ```d
> void main( string[] args ){
> 
>      Atom* res = null;
> 
>      if( _DEBUG_VERBOSE )  writeln( "Args are: " ~ args.to!string );
> 
>      // Populate necessary interpreter components
>      init_SPARROW();
> 
>      // ... Interpreter repeatedly invokes primitive symbol "rand"
> 
> }
> ```
> 
> Output:
> ```
> 0.961451
> 0.961451
> 0.961451
> 0.961451
> 0.961451
> 0.961451
> ```
> 
> Note: I have enclosed `uniform` so deeply because I am implementing the 
> random number feature of a [computer 
> language](https://github.com/jwatson-CO-edu/SPARROW).
> 
> ---
> 
> What is the reason for this? Has the compiler optimized away the 
> `uniform` call to a single double number?
> What is the main difference between Program 1 and Program 2? Both seem to:
> * Have a global RNG `rnd`
> * Seed RNG after `main` starts.
> * Generates a random number on [1,0) from a function.
> 
> So I would expect both programs to behave the same...
> 
> 

Without the rest of the code, and how random is called, I have a 
hunch... Are you using threads by any chance?

If, for instance, your calls to rand01 are done in a new thread, that 
new thread will have a *default* state of Mt19937.

I tried out just a non-seeded instance, and it did not produce that 
exact number, so this may not be the case.

But in case you are, you should be aware that globals get one instance 
per thread, and are default initialized.

-Steve


More information about the Digitalmars-d-learn mailing list