Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement the following random generator in PHP

The following code in Scala and CPP generates an identical sequence of random numbers. I am trying to write the equivalent code in PHP but having some difficulties.

class Rand {
    long int seed;

    public:

        Rand(long int _seed) {
            seed = _seed;
        }

        int next(int bits) {
            seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1); 
            return (seed >> (48 - bits));
        }

        int nextInt() {
            return next(32);
        }
};

Scala:

class Random(initialSeed: Long) {
    var seed: Long = initialSeed

    def setSeed(s: Long): Unit = {
        seed = s
    }

    def next(bits: Int): Int = {
        seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1)

        (seed >>> (48 - bits)).toInt
    }

    def nextInt() = next(32)
}

So far in PHP I have the following but it's way off. I think the main difficulty is simulating the 32 bit and 64 bit integers that CPP and Scala/Java are able to do explicitly.

<?php
    class Rand {
        protected $rseed;

        function __construct($s) {
            $rseed = $s;
        } 

        public function rnext($bits) {
            $a = ($this->rseed * 0x5DEECE66D + 0xB);
            $b = (1 << 48) - 1;

            $this->rseed = $a & $b;
            // implementation note - in JAVA the next line has >>> not >> which does a zero fill of the shifted
            // value which probably is important and must be simulated in PHP
            $ret = ($this->rseed >> (48 - $bits));

            return $ret;
        }

        public function nextInt() {
            return $this->rnext(32);
        }
    }

    $r = new Rand(916916916);
    echo "rand " . $r->nextInt();
like image 557
justinhj Avatar asked Apr 29 '26 20:04

justinhj


1 Answers

I think a library like gmp might be the answer. This is an attempt, not sure if it's correct and it can probably be cleaned up a bit...

class Rand {
    protected $rseed;
    private $mul;
    private $add;

    function __construct($s) {
        $this->rseed = $s;
        $this->mul = gmp_init(0x5DEECE66D);
        $this->add = gmp_init(0xB);
    } 

    public function rnext($bits) {

        $a = gmp_add(gmp_mul(gmp_init($this->rseed), $this->mul), $this->add);
        $aInt = gmp_intval(gmp_mod($a, gmp_init(PHP_INT_MAX)));

        $b = (1 << 48) - 1;

        $this->rseed = $aInt & $b;
        $ret = ($this->rseed >> (48 - $bits));

        return $ret;
    }

    public function nextInt() {
        return $this->rnext(32);
    }
}

$r = new Rand(916916916);
echo "rand " . $r->nextInt();
like image 138
monocell Avatar answered May 01 '26 11:05

monocell