Skip to content

Corner case: Would it be possible to add int32 and uint32? #13

@scottchiefbaker

Description

@scottchiefbaker

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions