如何在 Perl 中进行无符号 32 位算术运算?

How to do unsigned 32 bit arithmetic in Perl?

我想在 Perl 中实现以下 C 程序:

#include <stdio.h>
#include <stdint.h>

uint32_t xorshift32 ()
{
  static uint32_t y = 2463534242;
  y ^= y << 13;
  y ^= y >> 17;
  y ^= y << 5;
  return y;
}

int main (int argc, char *argv[])
{
  int n = 10;
  while (n-- > 0)
    printf ("%u\n", xorshift32());
}

输出为:

723471715
2497366906
2064144800
2008045182
3532304609
374114282
1350636274
691148861
746858951
2653896249

这是我失败的尝试:

{
  package Xorshift;
  use strict;
  use warnings;
  use integer;

  sub new
  {
    my $class = shift;
    bless { y => 2463534242 } => $class
  }

  sub rand ()
  {
    my $y = $_[0]->{y};
    $y ^= $y << 13;
    $y ^= $y >> 17;
    $y ^= $y << 5;
    $_[0]->{y} = $y;
    return $y;
  }
}

my $xor = Xorshift->new;

my $n = 10;
while ($n-- > 0) {
  print $xor->rand(), "\n";
}

输出是这样的:

660888219700579
3396719463693796860
-1120433007023638100
2588568168682748299
1469630995924843144
-8422345229424035168
1449080611344244726
-4722527344582589597
8061824971057606814
-3113862584906767882

问题:

  1. Perl 使用 64 位算法。
  2. 整数是有符号的。

如何改为进行 32 位无符号算术运算?

如果你想模拟32位操作的结果,你可以简单地应用一个掩码:

{
  package Xorshift;
  use strict;
  use warnings;
  use integer;

  sub new
  {
    my $class = shift;
    bless { y => 2463534242 } => $class
  }
  
  sub to32{
    return ($_[0] & 0xFFFFFFFF);
  }

  sub rand ()
  {
    my $y = $_[0]->{y};
    $y ^= to32($y << 13);
    $y ^= to32($y >> 17);
    $y ^= to32($y << 5);
    $_[0]->{y} = $y;
    return $y;
  }
}

my $xor = Xorshift->new;

my $n = 10;
while ($n-- > 0) {
  print $xor->rand(), "\n";
}