Port of Random Generator from C to Java

Port of Random generator from C to Java?

Can anyone port this to Java? How does
this work when you only have signed
numbers available?

No Stress! a=18782 so the largest t could ever be is not large enough to cause signed vs. unsigned problems. You would have to "upgrade" the result of using Q to a value equal to a 32-bit unsigned number before using it anywhere. e.g. if Q is an int (32-bit signed) then you'd have to do this before using it in the t=a*Q[i]+c statement, e.g.

t=a*(((long)Q[i])&0xffffffffL)+c

where this (((long)Q[i])&0xffffffffL) business promotes Q[i] to a 64-bit # and ensures its high 32 bits are 0's. (edit: NOTE: you need 0xffffffffL here. Java does the wrong thing if you use 0xffffffff, it seems like it "optimizes" itself to the wrong answer & you get a negative number if Q[i]'s high bit is 1.)

You should be able to verify this by running the algorithms in C++ and Java to compare the outputs.

edit: here's a shot at it. I tried running it in C++ and Java for N=100000; they both match. Apologies if I used bad Java idioms, I'm still fairly new to Java.

C++:

// marsaglia2003.cpp 

#include <stdio.h>
#include <stdlib.h> // for atoi

class m2003
{
enum {c0=362436, sz=4096, mask=4095};
unsigned long Q[sz];
unsigned long c;
short i;

public:
m2003()
{
// a real program would seed this with a good random seed
// i'm just putting in something that makes the output interesting
for (int j = 0; j < sz; ++j)
Q[j] = j + (j << 16);
i = 4095;
c = c0;
}

unsigned long next()
{
unsigned long long t, a=18782LL;
unsigned long x;
unsigned long r=0xfffffffe;
i = (i+1)&mask;
t=a*Q[i]+c;
c=(unsigned long)(t>>32);
x=(unsigned long)t + c;
if (x<c)
{
x++;
c++;
}
return (Q[i]=r-x);
}
};

int main(int argc, char *argv[])
{
m2003 generator;
int n = 100;
if (argc > 1)
n = atoi(argv[1]);

for (int i = 0; i < n; ++i)
{
printf("%08x\n", generator.next());
}
return 0;
}

java: (slower than compiled C++ but it matches for N=100000)

// Marsaglia2003.java

import java.util.*;

class Marsaglia2003
{
final static private int sz=4096;
final static private int mask=4095;
final private int[] Q = new int[sz];
private int c=362436;
private int i=sz-1;

public Marsaglia2003()
{
// a real program would seed this with a good random seed
// i'm just putting in something that makes the output interesting
for (int j = 0; j < sz; ++j)
Q[j] = j + (j << 16);
}

public int next()
// note: returns a SIGNED 32-bit number.
// if you want to use as unsigned, cast to a (long),
// then AND it with 0xffffffffL
{
long t, a=18782;
int x;
int r=0xfffffffe;
i = (i+1)&mask;
long Qi = ((long)Q[i]) & 0xffffffffL; // treat as unsigned 32-bit
t=a*Qi+c;
c=(int)(t>>32);
// because "a" is relatively small this result is also small

x=((int)t) + c;
if (x<c && x>=0) // tweak to treat x as unsigned
{
x++;
c++;
}
return (Q[i]=r-x);
}

public static void main(String args[])
{
Marsaglia2003 m2003 = new Marsaglia2003();

int n = 100;
if (args.length > 0)
n = Integer.parseInt(args[0]);
for (int i = 0; i < n; ++i)
{
System.out.printf("%08x\n", m2003.next());
}
}
};

Exact C equivalent of Java Random.nextInt(int bound) method

Java JDK sources are publicly available.

If you want an exact equivalent of Java's random number generator in C, go grab the sources and write/port it yourself.

C#/Java Number Randomization

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.)

Effort needed to port from C to Java

Here's a very rough metric:

12 + [number of lines]/1000 - [number of comments]/50
+ [number of functions]/100 + [number of pointer variables]/50
+ [number of macros]/10 + [number of bitwise operators]/5
+ [number of #if[def]s]/3 + [number of function pointers]/2
+ [number of pointer casts and unions]/2
- [average variable name length]

You get a figure in hours.

C's stdlib rand() function in Java

The C standard does not dictate the implementations of srand() and rand(). As such, different environments (OS, C libraries, architecture, etc.) will more than likely produce sequences of numbers that are different for the same seed value.

Also, the implementation Java's Random class is not bound to any particular algorithm. Here again, different JVMs may very well produce different sequences for the same seed value. In addition, the implementation will more than likely not be tied to the standard C functions. Which means, the Java produced sequence will be different than a C sequence using the same seed.

If you truly need to generate random sequence in Java to match exactly that of the standard C functions, the best you could hope to do is replicate the sequence for a particular environment. This would require creating a JNI library to proxy calls to srand() and rand() or creating some other external process that makes the calls and is invoked from Java. Either way, that's a lot of complexity and more program maintenance.

If in fact all you need are random sequences that appear to be uniformly distributed, regardless of the exact values, then use Random as is. It is more than sufficient for most RNG needs.

Generate True Random Number Generator in any of programming language

You are trying to generate a random number using only a deterministic alghorithm, expresed in some programming language like java. It is not possible to create a true random number generator in a deterministic device.

By the very definition of deterministic we know that if a device is configured in the same state it will always exhibit the same behaviour.

In the particular case of a true random generator the device would be an algorithm with no input and one output (the dessired random number). Under such conditions a deterministic algorithm can only produce always the same number. Thus not random.

Pseudorandom generators imitate randomness by storing an internal state they use to produce a sequence of numbers with an appearance of randomness. Conceptually that internal state is just another input of the algorithm and for the same internal state the algorithm will always produce the same output. Though these algorithms provide a stream of changing numbers they are not at all truly random because they will always produce the same string of numbers.

You can try to improve a bit more by initializing the internal state of such pseudorandom algorithm with a different value each time, thus getting different stream of random numbers. But this poses two problems :

  • Where do you get that initial state from? If you always use the same initial state you don't get different streams of numbers. And trying to algorithmically (thus deterministically) get a random state is just the same problem again.
  • Even if you get a true random initial state from a physical source the stream of numbers will still not be truly random. Each number is calculated by a deterministic algorithm from the previous state. Thus by examining a long stream of numbers it is possible to eventually know what will the next number be.

It is actually possible to create a random number generator using an algorithm. You would have to use a nondeterministic algorithm. But such algorithms require a random number generator themselves in order to be nondeterministic. Such as physical devices or race conditions.

Get random port for UDP socket

Call bind() specifying port 0. That will allow the OS to pick an unused port. You can then use getsockname() to retreive the chosen port.



Related Topics



Leave a reply



Submit