最近踩了個坑。。。首先,來看個例子吧。html
console.log(4000000000 >> 1);複製代碼
將上面代碼在瀏覽器中運行,你會獲得什麼結果呢?瀏覽器
將操做數看成32位的比特序列(由0和1組成),操做操做數的二進制形式,返回值依然是標準的JavaScript數值。ide
先將操做數轉換爲大端字節序的32位整數,並返回與左操做數相同類型的結果。htm
計算機是以字節爲單位進行存儲的,一個字節是8位bit,用32位bit表示的整數會佔4個字節,這4個字節的在計算機中存儲的相對位置關係就構成了字節序。blog
簡單來講,大端字節序就是32位整數中,高位字節在前,和咱們平時的閱讀順序是一致的。ip
上面的知識有點抽象,看過以後應該手動黑人問號❓get
爲了簡單起見,咱們用2^31(16進製表示爲8FFF)這個數來進行問題出現的緣由。it
var num = Math.pow(2, 31);console.log(num >> 1);複製代碼
num的32位bit表示爲:1000,0000,0000,0000console
右移一位後數值的二進制表示爲:1100,0000,0000,0000class
按照有符號數在計算機內的表示形式(二進制補碼),具體內容能夠參考這篇文章。咱們能夠將移位後的二進制補碼轉換成原碼:
32位補碼1000,0000,0000,0000,表示的有符號數是:-Math.pow(2,31) = -2147483648, 這個數右移一位(除以2)後,就是-1073741824
粗暴截取低32位,而後按照上述方式進行移動,能夠試試下面的代碼,應該能進一步理解。
console.log(Math.pow(2,32) >> 1);console.log((Math.pow(2,32) + Math.pow(2,31)) >> 1);複製代碼
因爲JavaScript自己能表示的整數是比較大的(能夠經過Number.MAX_SAFE_INTEGER進行查看),因此反倒顯得其右移操做比較奇怪。
在不能肯定數值的大小範圍時,仍是老老實實使用除法操做會比較好