How to implement C's drand48 and srand48 in Java?

1

I need to implement C's drand48() and srand48() random number generator and initializer for a programming project written in Java. The program needs to mimic the generation of a pseudo random number from these functions in C given a specific seed.

According to the man pages:

All the functions work by generating a sequence of 48-bit integers, Xi, according to the linear congruential formula:

Xn+1 = (aXn + c) mod m, where n >= 0

The parameter m = 2^48, hence 48-bit integer arithmetic is performed. Unless lcong48() is called, a and c are given by:

a = 0x5DEECE66D
c = 0xB

In this srand48() implementation below, I set the high order 32-bits of Xi to the argument seedval. The low order 16-bits are set to the arbitrary value 0x330E, according to the man pages. I do not understand how to apply the congruential formula to extract a random number. Any help would be greatly appreciated, thanks!

public void srand48(long seedval) {
  this.seed = seedval & 0xFFFFFFFF;
  this.seed = (this.seed << 16) | 0x330E;
}

public double drand48() {
  this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
  return this.seed;
}

The numbers that come out when drand48() is called are out of the range [0.0, 1.0). Could someone also explain why 48 bits is so significant for this pseudo random number generation?

java
c
random
asked on Stack Overflow Jul 7, 2019 by Chris Turgeon • edited Jul 7, 2019 by Marco Bonelli

1 Answer

2

Your implementation looks fine. The values you get are out of range because you're returning this.seed directly. You should normalize the result between 0.0 and 1.0 first, then return it. Also, make sure this.seed is a long.

The correct code would be:

public double drand48() {
    this.seed = (0x5DEECE66DL * this.seed + 0xBL) & ((1L << 48) - 1);
    return (double)this.seed / (1L << 48);
}
answered on Stack Overflow Jul 7, 2019 by Marco Bonelli • edited Jul 7, 2019 by Marco Bonelli

User contributions licensed under CC BY-SA 3.0