剛好在寫LeetCode 190, 191時遇到要如何處理正負數的位移問題,因為題目要求的是傳入的值會是一個32bits長度的數,但是在javascript 中這就可能會是個正整數或負整數,所以需要的處理方式不一樣…
大概問了下gpt主要在js中有三種位移符號
- 左移運算符 (
<<
):這個運算符將數字的二進位表示向左移動指定的位數。左移後,右邊空出的位將被0填充。這是有符號左移,會考慮符號位。
假設我們有一個正整數
x = 5
,在二進制中表示為0000 0000 0000 0000 0000 0000 0000 0101
。我們對
x
執行左移1位的操作 (x << 1
),結果會是:
x << 1
:0000 0000 0000 0000 0000 0000 0000 1010
在十進制中,這個數字是10(5的兩倍)。左移一位基本上等於乘以2。
- 帶符號右移運算符 (
>>
):這個運算符將數字的二進位表示向右移動指定的位數。右移後,左邊空出的位將由原來的符號位(即最左邊的位)填充。這允許負數在右移後保持為負數。
假設我們有一個負整數
y = -5
,它在32位二進制補碼中的表示為1111 1111 1111 1111 1111 1111 1111 1011
。進行
y << 1
操作,結果會是:
y << 1
:1111 1111 1111 1111 1111 1111 1111 0110
在十進制中,這個數字是-10。類似於正數的情況,左移一位相當於乘以2,但符號保持不變。
- 無符號右移運算符 (
>>>
):這個運算符也將數字的二進位表示向右移動,但移動後左邊空出的位將被0填充,不考慮符號位。這意味著結果總是非負的。
假設我們有一個負整數
y = -8
,它在32位二進制補碼中的表示為1111 1111 1111 1111 1111 1111 1111 1000
。進行
y >>> 1
操作,結果會是:
y >>> 1
:0111 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以為持此數的正負號)