javascript中負(fù)數(shù)算術(shù)右移、邏輯右移的奧秘探索
更新時(shí)間:2013年10月17日 17:50:17 作者:
javascript中負(fù)數(shù)的算術(shù)右移和邏輯右移都十分的讓人迷惑,特別是邏輯右移,接下來的文章中將為大家詳細(xì)介紹下為什么右移之后,一個(gè)很小的負(fù)數(shù)也會(huì)得到一個(gè)無比巨大的數(shù)
javascript中負(fù)數(shù)的算術(shù)右移和邏輯右移都十分的讓人迷惑,特別是邏輯右移>>>,你會(huì)發(fā)現(xiàn)即使一個(gè)很小的負(fù)數(shù),右移之后,也會(huì)得到一個(gè)無比巨大的數(shù),這是為什么呢?
原來在邏輯右移中符號(hào)位會(huì)隨著整體一起往右移動(dòng),這樣就是相當(dāng)于無符號(hào)數(shù)的移動(dòng)了,最后得到的就是一個(gè)正數(shù),因?yàn)榉?hào)位不存在了。首先邏輯右移產(chǎn)生的一定是32位的數(shù),然后負(fù)數(shù)的符號(hào)位為1,這意味著從第32位到符號(hào)位的位置全部由1填充,這樣的數(shù)能不大嗎例如-1,邏輯右移0位表現(xiàn)形式就是1111 1111 1111 1111 1111 1111 1111 1111 ,這樣的數(shù)是當(dāng)作正數(shù)來對(duì)待的!所以將-1邏輯右移N位,最后的結(jié)果都是全為1!
左移運(yùn)算保留數(shù)字的符號(hào)位。例如,如果把 -2 左移 5 位,得到的是 -64,而不是 64?!胺?hào)仍然存儲(chǔ)在第 32 位中嗎?”是的,不過這在 ECMAScript 后臺(tái)進(jìn)行,開發(fā)者不能直接訪問第 32 個(gè)數(shù)位。即使輸出二進(jìn)制字符串形式的負(fù)數(shù),顯示的也是負(fù)號(hào)形式(例如,-2 將顯示 -10。)
有符號(hào)右移運(yùn)算
有符號(hào)右移運(yùn)算符由兩個(gè)大于號(hào)表示(<$lt;)。它把 32 位數(shù)字中的所有數(shù)位整體右移,同時(shí)保留該數(shù)的符號(hào)(正號(hào)或負(fù)號(hào))。有符號(hào)右移運(yùn)算符恰好與左移運(yùn)算相反。例如,把 64 右移 5 位,將變?yōu)?2:
var iOld = 64; //等于二進(jìn)制 1000000
var iNew = iOld >> 5; //等于二進(jìn)制 10 十進(jìn)制 2同樣,移動(dòng)數(shù)位后會(huì)造成空位。這次,空位位于數(shù)字的左側(cè),但位于符號(hào)位之后。ECMAScript 用符號(hào)位的值填充這些空位,創(chuàng)建完整的數(shù)字,如下圖所示:
無符號(hào)右移運(yùn)算
無符號(hào)右移運(yùn)算符由三個(gè)大于號(hào)(>>>)表示,它將無符號(hào) 32 位數(shù)的所有數(shù)位整體右移。對(duì)于正數(shù),無符號(hào)右移運(yùn)算的結(jié)果與有符號(hào)右移運(yùn)算一樣。
用有符號(hào)右移運(yùn)算中的例子,把 64 右移 5 位,將變?yōu)?2:
無符號(hào)右移運(yùn)算用 0 填充所有空位。對(duì)于正數(shù),這與有符號(hào)右移運(yùn)算的操作一樣,而負(fù)數(shù)則被作為正數(shù)來處理。
由于無符號(hào)右移運(yùn)算的結(jié)果是一個(gè) 32 位的正數(shù),所以負(fù)數(shù)的無符號(hào)右移運(yùn)算得到的總是一個(gè)非常大的數(shù)字。例如,如果把 -64 右移 5 位,將得到 134217726。如果得到這種結(jié)果的呢?
要實(shí)現(xiàn)這一點(diǎn),需要把這個(gè)數(shù)字轉(zhuǎn)換成無符號(hào)的等價(jià)形式(盡管該數(shù)字本身還是有符號(hào)的),可以通過以下代碼獲得這種形式:
var iUnsigned64 = -64 >>> 0;
然后,用 Number 類型的 toString() 獲取它的真正的位表示,采用的基為 2:代碼如下:
alert(iUnsigned64.toString(2));
這將生成 11111111111111111111111111000000,即有符號(hào)整數(shù) -64 的二進(jìn)制補(bǔ)碼表示,不過它等于無符號(hào)整數(shù) 4294967232。
出于這種原因,使用無符號(hào)右移運(yùn)算符要小心。
現(xiàn)在來說一下負(fù)數(shù)的算術(shù)右移>>:
我們發(fā)現(xiàn)-9>>2=-3,為什么是-3呢?
首先符號(hào)位是不變的,不參加右移,然后在9右移的過程中,最低位為1的話,那么右移之后最低位仍然為1!這是很奇怪的。
原來在邏輯右移中符號(hào)位會(huì)隨著整體一起往右移動(dòng),這樣就是相當(dāng)于無符號(hào)數(shù)的移動(dòng)了,最后得到的就是一個(gè)正數(shù),因?yàn)榉?hào)位不存在了。首先邏輯右移產(chǎn)生的一定是32位的數(shù),然后負(fù)數(shù)的符號(hào)位為1,這意味著從第32位到符號(hào)位的位置全部由1填充,這樣的數(shù)能不大嗎例如-1,邏輯右移0位表現(xiàn)形式就是1111 1111 1111 1111 1111 1111 1111 1111 ,這樣的數(shù)是當(dāng)作正數(shù)來對(duì)待的!所以將-1邏輯右移N位,最后的結(jié)果都是全為1!
左移運(yùn)算保留數(shù)字的符號(hào)位。例如,如果把 -2 左移 5 位,得到的是 -64,而不是 64?!胺?hào)仍然存儲(chǔ)在第 32 位中嗎?”是的,不過這在 ECMAScript 后臺(tái)進(jìn)行,開發(fā)者不能直接訪問第 32 個(gè)數(shù)位。即使輸出二進(jìn)制字符串形式的負(fù)數(shù),顯示的也是負(fù)號(hào)形式(例如,-2 將顯示 -10。)
有符號(hào)右移運(yùn)算
有符號(hào)右移運(yùn)算符由兩個(gè)大于號(hào)表示(<$lt;)。它把 32 位數(shù)字中的所有數(shù)位整體右移,同時(shí)保留該數(shù)的符號(hào)(正號(hào)或負(fù)號(hào))。有符號(hào)右移運(yùn)算符恰好與左移運(yùn)算相反。例如,把 64 右移 5 位,將變?yōu)?2:
var iOld = 64; //等于二進(jìn)制 1000000
var iNew = iOld >> 5; //等于二進(jìn)制 10 十進(jìn)制 2同樣,移動(dòng)數(shù)位后會(huì)造成空位。這次,空位位于數(shù)字的左側(cè),但位于符號(hào)位之后。ECMAScript 用符號(hào)位的值填充這些空位,創(chuàng)建完整的數(shù)字,如下圖所示:
無符號(hào)右移運(yùn)算
無符號(hào)右移運(yùn)算符由三個(gè)大于號(hào)(>>>)表示,它將無符號(hào) 32 位數(shù)的所有數(shù)位整體右移。對(duì)于正數(shù),無符號(hào)右移運(yùn)算的結(jié)果與有符號(hào)右移運(yùn)算一樣。
用有符號(hào)右移運(yùn)算中的例子,把 64 右移 5 位,將變?yōu)?2:
無符號(hào)右移運(yùn)算用 0 填充所有空位。對(duì)于正數(shù),這與有符號(hào)右移運(yùn)算的操作一樣,而負(fù)數(shù)則被作為正數(shù)來處理。
由于無符號(hào)右移運(yùn)算的結(jié)果是一個(gè) 32 位的正數(shù),所以負(fù)數(shù)的無符號(hào)右移運(yùn)算得到的總是一個(gè)非常大的數(shù)字。例如,如果把 -64 右移 5 位,將得到 134217726。如果得到這種結(jié)果的呢?
要實(shí)現(xiàn)這一點(diǎn),需要把這個(gè)數(shù)字轉(zhuǎn)換成無符號(hào)的等價(jià)形式(盡管該數(shù)字本身還是有符號(hào)的),可以通過以下代碼獲得這種形式:
var iUnsigned64 = -64 >>> 0;
然后,用 Number 類型的 toString() 獲取它的真正的位表示,采用的基為 2:代碼如下:
alert(iUnsigned64.toString(2));
這將生成 11111111111111111111111111000000,即有符號(hào)整數(shù) -64 的二進(jìn)制補(bǔ)碼表示,不過它等于無符號(hào)整數(shù) 4294967232。
出于這種原因,使用無符號(hào)右移運(yùn)算符要小心。
現(xiàn)在來說一下負(fù)數(shù)的算術(shù)右移>>:
我們發(fā)現(xiàn)-9>>2=-3,為什么是-3呢?
首先符號(hào)位是不變的,不參加右移,然后在9右移的過程中,最低位為1的話,那么右移之后最低位仍然為1!這是很奇怪的。
您可能感興趣的文章:
- js的邏輯運(yùn)算符 ||
- JavaScript中的邏輯判斷符&&、||與!介紹
- js比較和邏輯運(yùn)算符的介紹
- 基于邏輯運(yùn)算的簡(jiǎn)單權(quán)限系統(tǒng)(實(shí)現(xiàn)) JS 版
- 用JavaScript實(shí)現(xiàn)一個(gè)代碼簡(jiǎn)潔、邏輯不復(fù)雜的多級(jí)樹
- js針對(duì)ip地址、子網(wǎng)掩碼、網(wǎng)關(guān)的邏輯性判斷
- JSP教程之使用JavaBean完成業(yè)務(wù)邏輯的方法
- 詳解JavaScript邏輯And運(yùn)算符
- 詳解JavaScript邏輯Not運(yùn)算符
- Javascript中常見的邏輯題和解決方法
相關(guān)文章
微信小程序?qū)W習(xí)筆記之獲取位置信息操作圖文詳解
這篇文章主要介紹了微信小程序?qū)W習(xí)筆記之獲取位置信息操作,結(jié)合實(shí)例形式分析了微信小程序獲取位置信息的原理、步驟及相關(guān)操作注意事項(xiàng),并結(jié)合圖文形式予以說明,需要的朋友可以參考下2019-03-03
JavaScript異步調(diào)用定時(shí)方法并停止該方法實(shí)現(xiàn)代碼
JavaScript異步調(diào)用定時(shí)方法并停止該方法實(shí)現(xiàn)代碼 ,需要的朋友可以參考下2012-03-03
JavaScript類型相關(guān)的常用操作總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于JavaScript類型相關(guān)的常用操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
JS獲取復(fù)選框的值,并傳遞到后臺(tái)的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄狫S獲取復(fù)選框的值,并傳遞到后臺(tái)的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05
layui 關(guān)閉open彈出框 刷新table表格頁面的方法
今天小編就為大家分享一篇layui 關(guān)閉open彈出框 刷新table表格頁面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-09-09
用JS實(shí)現(xiàn)3D球狀標(biāo)簽云示例代碼
3D球狀標(biāo)簽云的效果想必很多朋友在瀏覽網(wǎng)頁時(shí)都有見到過吧,看起來提復(fù)雜的,其實(shí)實(shí)現(xiàn)起來挺容易的,感興趣的朋友可以了解下本文2013-12-12
JavaScript表單驗(yàn)證實(shí)例之驗(yàn)證表單項(xiàng)是否為空
表單驗(yàn)證幾乎在每個(gè)需要注冊(cè)或者是登錄的網(wǎng)站都是必不可少,下面通過本篇文章給大家介紹JavaScript表單驗(yàn)證實(shí)例之驗(yàn)證表單項(xiàng)是否為空,涉及到j(luò)s表單驗(yàn)證實(shí)例相關(guān)知識(shí),對(duì)js表單驗(yàn)證實(shí)例代碼需要的朋友一起學(xué)習(xí)吧2016-01-01

