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 equivalent code in PHP, but with some difficulty.

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 far away. I think the main difficulty lies in the modeling of 32bit and 64bit integers that CPP and Scala / Java can 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();

      

+3


source to share


1 answer


I think a library like gmp might be the answer. This is an attempt, not sure if this is correct and 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();

      

+1


source







All Articles