尝试使用Perl将位移位为负数时,我遇到了问题。 例如:
printf("%d", (-10) >> 2);
此方法打印:1073741821
在相同条件下,当我尝试使用Javascript:
时document.write('test: ' + (-10 >> 2) + '<br>');
输出为-3
我想了解Perl和Javascripts之间的区别。 Perl是否有将位移位为负数的问题?
非常感谢。
答案 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。