Perl移位问题

时间:2010-12-02 19:58:36

标签: perl

尝试使用Perl将位移位为负数时,我遇到了问题。 例如:

printf("%d", (-10) >> 2);

此方法打印:1073741821

在相同条件下,当我尝试使用Javascript:

document.write('test: ' + (-10 >> 2) + '<br>');

输出为-3

我想了解Perl和Javascripts之间的区别。 Perl是否有将位移位为负数的问题?

非常感谢。

2 个答案:

答案 0 :(得分:10)

Perl使用无符号二进制右移。如果Perl在32位体系结构上运行,则会得到以下结果:

-10 == -0xa == 0xfffffff6
0xfffffff6 >> 2 == 0x3ffffffd == 1073741821

无符号二进制右移意味着结果的最高(最严格)位变为0。

JavaScript使用符号扩展二进制右移。 JavaScript移位始终将输入和输出视为32位整数。所以你得到:

-10 == -0xa == 0xfffffff6
-3 == -0x3 == 0xfffffffd
0xfffffff6 >> 2 == 0xfffffffd == -3

符号扩展二进制右移意味着结果的最高(最严格)位从原始值的最高位复制。

正如Tim Henigan在他的回答中所说,通过指定use integer;,可以从Perl获得符号扩展二进制右移。例如:

{ use integer;
  printf "%d 0x%x\n", (-10) >> 2, (-10) >> 2;  #: -3 0xfffffffd
}
printf "%d 0x%x\n", (-10) >> 2, (-10) >> 2;  #: 1073741821 0x3ffffffd

答案 1 :(得分:8)

如果是一个选项,您可以使用use integer更正此签名的右移。

例如:

use integer;
printf("%d", (-10) >> 2);

...产生正确的结果(-3)。

来自perlop

  

请注意“&lt;&lt;&lt;”和“&gt;&gt;”在Perl   使用“&lt;&lt;”直接实现   和“&gt;&gt;”在C.如果use integer(见   整数算术)然后生效   使用带符号的C整数,否则   使用无符号C整数。或   方式,实施不会   生成大于大小的结果   构建了Perl的整数类型   (32位或64位)。

有关详细信息,请参阅integer perldoc