-
Notifications
You must be signed in to change notification settings - Fork 6
Open
Description
I am attempting to implement PCG32 in Perl.
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;
uint32_t pcg32_random_r(pcg32_random_t* rng)
{
uint64_t oldstate = rng->state;
// Advance internal state
rng->state = oldstate * 6364136223846793005ULL + (rng->inc|1);
// Calculate output function (XSH RR), uses old state for max ILP
uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}Using Math::Int64 I'm able to get it working pretty well:
my $seed1 = uint64(12);
my $seed2 = uint64(34);
my $x = pcg(\$seed1, \$seed2);
say $x;
sub pcg32 {
my ($state, $inc) = @_;
my $oldstate = $$state;
$$state = $oldstate * 6364136223846793005 + ($$inc | 1);
my $xorshifted = (($oldstate >> 18) ^ $oldstate) >> 27;
$xorshifted = $xorshifted & 0xFFFFFFFF;
my $rot = $oldstate >> 59;
my $invrot = 4294967296 - $rot;
my $ret = ($xorshifted >> $rot) | ($xorshifted << ($invrot & 31));
$ret = $ret & 0xFFFFFFFF;
return $ret;
}PCG32 declares a couple of variables ($xorshifted, $rot, and $ret) as uint32_t. Since we don't have a that in Perl I have to "fake" it in Perl by doing the math in 64 bit, and then masking off (bitwise and 0xFFFFFFFF) anything above 32 bits. It works but it feels kinda hacky. If there was a uint32() function in your library it would save me the hassle of converting and probably speed things up. I acknowledge the need for 32bit integers is pretty corner casey, but it would help me.
Metadata
Metadata
Assignees
Labels
No labels