# Rand() needs a seed?

**URL:** <https://www.ruby-forum.com/t/rand-needs-a-seed/142307>\
**Category:** IronRuby\
**Created:** [July 6, 2008, 4:29pm UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307 "2008-07-06T16:29:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Johan\_Danforth](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/48db29/32.png) [@Johan\_Danforth](https://www.ruby-forum.com/u/Johan_Danforth)\
**Post date:** [July 6, 2008, 4:29pm UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307/1 "2008-07-06T16:29:01Z")

</div>

I’m a noob Ruby user, but IronRuby behaves different from other Ruby  
implementations that I’ve tried, in IronRuby (rev 121) this code:

100.times {p rand(100)}

Often returns the same value for (almost) all iterations, like this:

2  
2  
2  
2  
2  
2  
2  
2  
…and so on…

Works as designed? Need to seed it or something?

/Johan

---

<div class="post-metadata">

**Author:** ![Johan\_Danforth](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/48db29/32.png) [@Johan\_Danforth](https://www.ruby-forum.com/u/Johan_Danforth)\
**Post date:** [July 6, 2008, 5:16pm UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307/2 "2008-07-06T17:16:42Z")

</div>

By default, the parameterless constructor of the System.Random class  
(which is what we’re using) uses the system time as the initial seed.  
Every time you ask for a random number, we create a new Random object,  
and in a tight loop like yours, they’ll probably all get the same seed.

We should probably create a single Random object the first time that one  
is requested and store it in the RubyContext.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 7:28 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] rand() needs a seed?

I’m a noob Ruby user, but IronRuby behaves different from other Ruby  
implementations that I’ve tried, in IronRuby (rev 121) this code:

100.times {p rand(100)}

Often returns the same value for (almost) all iterations, like this:

2  
2  
2  
2  
2  
2  
2  
2  
…and so on…

Works as designed? Need to seed it or something?

/Johan

---

<div class="post-metadata">

**Author:** ![Johan\_Danforth](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/48db29/32.png) [@Johan\_Danforth](https://www.ruby-forum.com/u/Johan_Danforth)\
**Post date:** [July 6, 2008, 6:51pm UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307/3 "2008-07-06T18:51:36Z")

</div>

Like this?

private static readonly Random rndGen = new Random();

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static double Rand(CodeContext/_!_/ context, object self) {  
lock(rndGen) return rndGen.NextDouble();  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, int  
limit) {  
if (limit == 0) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, double  
limit) {  
if (limit \< 1) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

I put a lock() on each call as well, because I believe the Next-methods  
aren’t thread safe. Works for me.

/Johan

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: den 6 juli 2008 17:16  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

By default, the parameterless constructor of the System.Random class  
(which is what we’re using) uses the system time as the initial seed.  
Every time you ask for a random number, we create a new Random object,  
and in a tight loop like yours, they’ll probably all get the same seed.

We should probably create a single Random object the first time that one  
is requested and store it in the RubyContext.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 7:28 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] rand() needs a seed?

I’m a noob Ruby user, but IronRuby behaves different from other Ruby  
implementations that I’ve tried, in IronRuby (rev 121) this code:

100.times {p rand(100)}

Often returns the same value for (almost) all iterations, like this:

2  
2  
2  
2  
2  
2  
2  
2  
…and so on…

Works as designed? Need to seed it or something?

/Johan

---

<div class="post-metadata">

**Author:** ![Johan\_Danforth](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/48db29/32.png) [@Johan\_Danforth](https://www.ruby-forum.com/u/Johan_Danforth)\
**Post date:** [July 6, 2008, 8:50pm UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307/4 "2008-07-06T20:50:10Z")

</div>

Something like that, yes, but making it a static member of KernelOps  
means that we have to pay the construction cost during startup. For a  
function as infrequently used as “rand”, it might be better to  
initialize it more lazily.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 9:51 AM  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

Like this?

private static readonly Random rndGen = new Random();

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static double Rand(CodeContext/_!_/ context, object self) {  
lock(rndGen) return rndGen.NextDouble();  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, int  
limit) {  
if (limit == 0) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, double  
limit) {  
if (limit \< 1) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

I put a lock() on each call as well, because I believe the Next-methods  
aren’t thread safe. Works for me.

/Johan

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: den 6 juli 2008 17:16  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

By default, the parameterless constructor of the System.Random class  
(which is what we’re using) uses the system time as the initial seed.  
Every time you ask for a random number, we create a new Random object,  
and in a tight loop like yours, they’ll probably all get the same seed.

We should probably create a single Random object the first time that one  
is requested and store it in the RubyContext.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 7:28 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] rand() needs a seed?

I’m a noob Ruby user, but IronRuby behaves different from other Ruby  
implementations that I’ve tried, in IronRuby (rev 121) this code:

100.times {p rand(100)}

Often returns the same value for (almost) all iterations, like this:

2  
2  
2  
2  
2  
2  
2  
2  
…and so on…

Works as designed? Need to seed it or something?

/Johan

---

<div class="post-metadata">

**Author:** ![Johan\_Danforth](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/48db29/32.png) [@Johan\_Danforth](https://www.ruby-forum.com/u/Johan_Danforth)\
**Post date:** [July 7, 2008, 12:03am UTC](https://www.ruby-forum.com/t/rand-needs-a-seed/142307/5 "2008-07-07T00:03:04Z")

</div>

Note there is also srand() method that seeds the generator. The  
generator therefore needs to be associated with RubyExecutionContext.

Tomas

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: Sunday, July 06, 2008 11:49 AM  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

Something like that, yes, but making it a static member of KernelOps  
means that we have to pay the construction cost during startup. For a  
function as infrequently used as “rand”, it might be better to  
initialize it more lazily.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 9:51 AM  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

Like this?

private static readonly Random rndGen = new Random();

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static double Rand(CodeContext/_!_/ context, object self) {  
lock(rndGen) return rndGen.NextDouble();  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, int  
limit) {  
if (limit == 0) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

[RubyMethod(“rand”, RubyMethodAttributes.PrivateInstance)]  
[RubyMethod(“rand”, RubyMethodAttributes.PublicSingleton)]  
public static object Rand(CodeContext/_!_/ context, object self, double  
limit) {  
if (limit \< 1) return Rand(context, self);  
lock (rndGen) return  
RuntimeHelpers.Int32ToObject((int)(rndGen.NextDouble() \* (limit - 1)));  
}

I put a lock() on each call as well, because I believe the Next-methods  
aren’t thread safe. Works for me.

/Johan

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Curt  
Hagenlocher  
Sent: den 6 juli 2008 17:16  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Ironruby-core] rand() needs a seed?

By default, the parameterless constructor of the System.Random class  
(which is what we’re using) uses the system time as the initial seed.  
Every time you ask for a random number, we create a new Random object,  
and in a tight loop like yours, they’ll probably all get the same seed.

We should probably create a single Random object the first time that one  
is requested and store it in the RubyContext.

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Johan Danforth  
Sent: Sunday, July 06, 2008 7:28 AM  
To: removed\_email\_address@domain.invalid  
Subject: [Ironruby-core] rand() needs a seed?

I’m a noob Ruby user, but IronRuby behaves different from other Ruby  
implementations that I’ve tried, in IronRuby (rev 121) this code:

100.times {p rand(100)}

Often returns the same value for (almost) all iterations, like this:

2  
2  
2  
2  
2  
2  
2  
2  
…and so on…

Works as designed? Need to seed it or something?

/Johan
