2010-12-02 70 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