Is it possible, from .NET, to mimic the exact randomization that Java uses? I have a seed, and I would like to be able to recieve the same results in both C# and Java when creating a random number.
-
And how random is that?... Just asking..Filip Ekberg– Filip Ekberg2010-01-27 14:24:16 +00:00Commented Jan 27, 2010 at 14:24
-
@Filip: I think it's implicit that he just wants stochastic randomness.Will Vousden– Will Vousden2010-01-27 14:26:01 +00:00Commented Jan 27, 2010 at 14:26
-
1@Filip: For some things it's imperative that you get the exact results even on multiple runs—simulations for example. You can't just say »Hey, I got these results but you can't reproduce them because they relied on my PRNG having a good day.«Joey– Joey2010-01-27 14:30:54 +00:00Commented Jan 27, 2010 at 14:30
6 Answers
You don't need to read the source code. The formula is a one-liner and is given in the documentation for java.util.Random.
Here's a partial translation:
[Serializable]
public class Random
{
public Random(UInt64 seed)
{
this.seed = (seed ^ 0x5DEECE66DUL) & ((1UL << 48) - 1);
}
public int NextInt(int n)
{
if (n <= 0) throw new ArgumentException("n must be positive");
if ((n & -n) == n) // i.e., n is a power of 2
return (int)((n * (long)Next(31)) >> 31);
long bits, val;
do
{
bits = Next(31);
val = bits % (UInt32) n;
}
while (bits - val + (n - 1) < 0);
return (int) val;
}
protected UInt32 Next(int bits)
{
seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
return (UInt32)(seed >> (48 - bits));
}
private UInt64 seed;
}
Example:
Random rnd = new Random(42);
Console.WriteLine(rnd.NextInt(10));
Console.WriteLine(rnd.NextInt(20));
Console.WriteLine(rnd.NextInt(30));
Console.WriteLine(rnd.NextInt(40));
Console.WriteLine(rnd.NextInt(50));
Output on both platforms is 0, 3, 18, 4, 20.
Comments
If you have the source code of the java.util.Random class for your Java implementation, you can easily port it to .NET.
If you require both applications (Java and .NET) to use a certain random number generator, you'd better implement one in both platforms and use it instead, as the system provided version might change its behavior as a result of an update.(Looks like the Java specification precisely describes the behavior of its PRNG.)
4 Comments
If you don't need a cryptographically secure pseudorandom number generator then I would go for the Mersenne twister. You can find source code for C# here and Java here.
2 Comments
java.util.Random isn't crypographically secure either so that's obviously not h(is|er) concern ;-)Well, you can look in the source code for Random.java and copy the algorithm, constants, etc.etc, but Random uses System.nanoTime in its constructor so you won't get the same results.
From java.util.Random
public Random() { this(++seedUniquifier + System.nanoTime()); }
I wouldn't be at all surprised if the source in C# would show you something similar.
Edit: Disregard, as has been pointed out, the constructor that takes an input seed never accesses time.
2 Comments
Random() - Takes nothing and uses Environment.TickCount and Random(int32 num) that takes your seed instead of the TickCount.