我尝试将以下C函数转换为Perl:
uint32_t xorshift32 (uint32_t x32)
{
x32 ^= x32 << 13;
x32 ^= x32 >> 17;
x32 ^= x32 << 5;
return x32;
}
我想出了以下内容:
sub xorshift32
{
my $r = '';
vec ($r, 0, 32) = int($_[0]);
vec ($r, 0, 32) ^= vec ($r, 0, 32) << 13;
vec ($r, 0, 32) ^= vec ($r, 0, 32) >> 17;
vec ($r, 0, 32) ^= vec ($r, 0, 32) << 5;
return vec ($r, 0, 32);
}
这是在Perl中强制32位溢出的规范方法还是有更好更快的方法呢?
我也不确定代码是否正确。移位操作的结果是否会在32位系统上浮动?
答案 0 :(得分:1)
我并不总是了解我的经典,但我喜欢0xFFFF_FFFF
这样的情况下的位掩码。
sub xorshift32 {
my $x32 = shift;
$x32 ^= $x32 << 13;
$x32 ^= (($x32 & 0xFFFF_FFFF) >> 17);
0xFFFF_FFFF & ($x32 ^ ($x32 << 5));
}
(尚未对此进行基准测试,不知道它与vec
的对比方式)
回答你的第二个问题,不,<<
位移操作的结果永远不会是一个浮点数,无论它是32位还是64位系统,即使两个操作数都是浮点数。
答案 1 :(得分:1)
只需在需要的地方添加& 0xFFFF_FFFF
。
sub xorshift32 {
my ($x32) = @_;
$x32 ^= ($x32 << 13) & 0xFFFF_FFFF;
$x32 ^= $x32 >> 17;
$x32 ^= ($x32 << 5) & 0xFFFF_FFFF;
return $x32;
}