Javascript中的位移符號

剛好在寫LeetCode 190, 191時遇到要如何處理正負數的位移問題,因為題目要求的是傳入的值會是一個32bits長度的數,但是在javascript 中這就可能會是個正整數或負整數,所以需要的處理方式不一樣…

大概問了下gpt主要在js中有三種位移符號

  1. 左移運算符 (<<):這個運算符將數字的二進位表示向左移動指定的位數。左移後,右邊空出的位將被0填充。這是有符號左移,會考慮符號位。

假設我們有一個正整數 x = 5,在二進制中表示為 0000 0000 0000 0000 0000 0000 0000 0101

我們對 x 執行左移1位的操作 (x << 1),結果會是:

x << 10000 0000 0000 0000 0000 0000 0000 1010

在十進制中,這個數字是10(5的兩倍)。左移一位基本上等於乘以2。

  1. 帶符號右移運算符 (>>):這個運算符將數字的二進位表示向右移動指定的位數。右移後,左邊空出的位將由原來的符號位(即最左邊的位)填充。這允許負數在右移後保持為負數。

假設我們有一個負整數 y = -5,它在32位二進制補碼中的表示為 1111 1111 1111 1111 1111 1111 1111 1011

進行 y << 1 操作,結果會是:

y << 11111 1111 1111 1111 1111 1111 1111 0110

在十進制中,這個數字是-10。類似於正數的情況,左移一位相當於乘以2,但符號保持不變。

  1. 無符號右移運算符 (>>>):這個運算符也將數字的二進位表示向右移動,但移動後左邊空出的位將被0填充,不考慮符號位。這意味著結果總是非負的。

假設我們有一個負整數 y = -8,它在32位二進制補碼中的表示為 1111 1111 1111 1111 1111 1111 1111 1000

進行 y >>> 1 操作,結果會是:

y >>> 10111 1111 1111 1111 1111 1111 1111 1100

在十進制中,這個數字是非常大的,因為無符號右移將負數轉換為正數。這個具體數值是2147483644(2^31-4)

這些例子展示了無符號右移運算符在正數和負數上的作用。對於正數,無符號右移一位與普通右移(帶符號)沒有區別,都相當於將數字除以2。

然而,對於負數,無符號右移會產生顯著不同的結果。由於無符號右移不考慮數字的符號位,它將原始數字視為一個非常大的正數,然後進行位移。這導致負數在經過無符號右移後變成一個非常大的正數。

結論:

在js中如果要處理unsighted intger的相關需求時,會有需要用到 >>> 符號,具體的使用方式如下:

  • 透過 value >>> 0 可以將value轉成正整數。
  • 如果 value 轉成 unsighted int 是一個大於 1<<31-1的正數,則如果要用右移運算符時,則第一次右移需要使用(>>>)運算符,之後就可以使用 (>>)右移運算符。
    (如果 value 在這時用的是 >> 運算符的話,則代表在使用完以後,還是會保留最左邊的1 bit以為持此數的正負號)