2010-12-02 38 views
4

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

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

这种方法打印:1073741821

用相同的条件下,当我尝试用JavaScript来做到这一点:

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

输出为-3

我想了解Perl和Javascript之间的不同。 Perl对于负数移位有问题吗?

非常感谢。

回答

10

Perl使用无符号二进制右移。如果Perl的在32位架构上运行,你会得到如下:

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

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

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

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

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

正如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 
7

如果是选项,您可以使用use integer更正此符号右移。

例如:

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

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

perlop

注意,这两个 “< <” 和 “>>” 在Perl 使用 “< <” 并直接实施了 “>>” 在C.如果use integer(见 整数算术)有效然后使用 有符号的C整数,否则使用无符号的C整数 。要么执行 的方式,执行的不会是 生成的结果大于整数类型Perl的大小 的结果是带有(32位或64位)的 。

欲了解更多信息,请登录integer perldoc