日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

js 位运算

發(fā)布時(shí)間:2023/12/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js 位运算 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

重溫整數(shù)

ECMAScript 整數(shù)有兩種類(lèi)型,即有符號(hào)整數(shù)(允許用正數(shù)和負(fù)數(shù))和無(wú)符號(hào)整數(shù)(只允許用正數(shù))。在 ECMAScript 中,所有整數(shù)字面量默認(rèn)都是有符號(hào)整數(shù),這意味著什么呢?

有符號(hào)整數(shù)使用 31 位表示整數(shù)的數(shù)值,用第 32 位表示整數(shù)的符號(hào),0 表示正數(shù),1 表示負(fù)數(shù)。數(shù)值范圍從 -2147483648 到 2147483647。

可以以?xún)煞N不同的方式存儲(chǔ)二進(jìn)制形式的有符號(hào)整數(shù),一種用于存儲(chǔ)正數(shù),一種用于存儲(chǔ)負(fù)數(shù)。正數(shù)是以真二進(jìn)制形式存儲(chǔ)的,前 31 位中的每一位都表示 2 的冪,從第 1 位(位 0)開(kāi)始,表示 20,第 2 位(位 1)表示 21。沒(méi)用到的位用 0 填充,即忽略不計(jì)。例如,下圖展示的是數(shù) 18 的表示法。

18 的二進(jìn)制版本只用了前 5 位,它們是這個(gè)數(shù)字的有效位。把數(shù)字轉(zhuǎn)換成二進(jìn)制字符串,就能看到有效位:

var iNum = 18; alert(iNum.toString(2)); //輸出 "10010"

這段代碼只輸出 "10010",而不是 18 的 32 位表示。其他的數(shù)位并不重要,因?yàn)閮H使用前 5 位即可確定這個(gè)十進(jìn)制數(shù)值。如下圖所示:

負(fù)數(shù)也存儲(chǔ)為二進(jìn)制代碼,不過(guò)采用的形式是二進(jìn)制補(bǔ)碼。計(jì)算數(shù)字二進(jìn)制補(bǔ)碼的步驟有三步:

  • 確定該數(shù)字的非負(fù)版本的二進(jìn)制表示(例如,要計(jì)算 -18的二進(jìn)制補(bǔ)碼,首先要確定 18 的二進(jìn)制表示)
  • 求得二進(jìn)制反碼,即要把 0 替換為 1,把 1 替換為 0
  • 在二進(jìn)制反碼上加 1
  • 要確定 -18 的二進(jìn)制表示,首先必須得到 18 的二進(jìn)制表示,如下所示:

    0000 0000 0000 0000 0000 0000 0001 0010

    接下來(lái),計(jì)算二進(jìn)制反碼,如下所示:

    1111 1111 1111 1111 1111 1111 1110 1101

    最后,在二進(jìn)制反碼上加 1,如下所示:

    1111 1111 1111 1111 1111 1111 1110 11011 --------------------------------------- 1111 1111 1111 1111 1111 1111 1110 1110

    因此,-18 的二進(jìn)制表示即 1111 1111 1111 1111 1111 1111 1110 1110。記住,在處理有符號(hào)整數(shù)時(shí),開(kāi)發(fā)者不能訪(fǎng)問(wèn) 31 位。

    有趣的是,把負(fù)整數(shù)轉(zhuǎn)換成二進(jìn)制字符串后,ECMAScript 并不以二進(jìn)制補(bǔ)碼的形式顯示,而是用數(shù)字絕對(duì)值的標(biāo)準(zhǔn)二進(jìn)制代碼前面加負(fù)號(hào)的形式輸出。例如:

    var iNum = -18; alert(iNum.toString(2)); //輸出 "-10010"

    這段代碼輸出的是 "-10010",而非二進(jìn)制補(bǔ)碼,這是為避免訪(fǎng)問(wèn)位 31。為了簡(jiǎn)便,ECMAScript 用一種簡(jiǎn)單的方式處理整數(shù),使得開(kāi)發(fā)者不必關(guān)心它們的用法。

    另一方面,無(wú)符號(hào)整數(shù)把最后一位作為另一個(gè)數(shù)位處理。在這種模式中,第 32 位不表示數(shù)字的符號(hào),而是值 231。由于這個(gè)額外的位,無(wú)符號(hào)整數(shù)的數(shù)值范圍為 0 到 4294967295。對(duì)于小于 2147483647 的整數(shù)來(lái)說(shuō),無(wú)符號(hào)整數(shù)看來(lái)與有符號(hào)整數(shù)一樣,而大于 2147483647 的整數(shù)則要使用位 31(在有符號(hào)整數(shù)中,這一位總是 0)。

    把無(wú)符號(hào)整數(shù)轉(zhuǎn)換成字符串后,只返回它們的有效位。

    注意:所有整數(shù)字面量都默認(rèn)存儲(chǔ)為有符號(hào)整數(shù)。只有 ECMAScript 的位運(yùn)算符才能創(chuàng)建無(wú)符號(hào)整數(shù)。

    位運(yùn)算 NOT

    位運(yùn)算 NOT 由否定號(hào)(~)表示,它是 ECMAScript 中為數(shù)不多的與二進(jìn)制算術(shù)有關(guān)的運(yùn)算符之一。

    位運(yùn)算 NOT 是三步的處理過(guò)程:

  • 把運(yùn)算數(shù)轉(zhuǎn)換成 32 位數(shù)字
  • 把二進(jìn)制數(shù)轉(zhuǎn)換成它的二進(jìn)制反碼
  • 把二進(jìn)制數(shù)轉(zhuǎn)換成浮點(diǎn)數(shù)
  • 例如:

    var iNum1 = 25; //25 等于 00000000000000000000000000011001 var iNum2 = ~iNum1;//轉(zhuǎn)換為 11111111111111111111111111100110 alert(iNum2); //輸出 "-26"

    位運(yùn)算 NOT 實(shí)質(zhì)上是對(duì)數(shù)字求負(fù),然后減 1,因此 25 變 -26。用下面的方法也可以得到同樣的方法:

    var iNum1 = 25; var iNum2 = -iNum1 -1; alert(iNum2); //輸出 -26

    位運(yùn)算 AND

    位運(yùn)算 AND 由和號(hào)(&)表示,直接對(duì)數(shù)字的二進(jìn)制形式進(jìn)行運(yùn)算。它把每個(gè)數(shù)字中的數(shù)位對(duì)齊,然后用下面的規(guī)則對(duì)同一位置上的兩個(gè)數(shù)位進(jìn)行 AND 運(yùn)算:

    第一個(gè)數(shù)字中的數(shù)位第二個(gè)數(shù)字中的數(shù)位結(jié)果
    111
    100
    010
    000

    例如,要對(duì)數(shù)字 25 和 3 進(jìn)行 AND 運(yùn)算,代碼如下所示:

    var iResult = 25 & 3; alert(iResult); //輸出 "1"

    25 和 3 進(jìn)行 AND 運(yùn)算的結(jié)果是 1。為什么?分析如下:

    25 = 0000 0000 0000 0000 0000 0000 0001 10013 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- AND = 0000 0000 0000 0000 0000 0000 0000 0001

    可以看出,在 25 和 3 中,只有一個(gè)數(shù)位(位 0)存放的都是 1,因此,其他數(shù)位生成的都是 0,所以結(jié)果為 1。

    位運(yùn)算 OR

    位運(yùn)算 OR 由符號(hào)(|)表示,也是直接對(duì)數(shù)字的二進(jìn)制形式進(jìn)行運(yùn)算。在計(jì)算每位時(shí),OR 運(yùn)算符采用下列規(guī)則:

    第一個(gè)數(shù)字中的數(shù)位第二個(gè)數(shù)字中的數(shù)位結(jié)果
    111
    101
    011
    000

    仍然使用 AND 運(yùn)算符所用的例子,對(duì) 25 和 3 進(jìn)行 OR 運(yùn)算,代碼如下:

    var iResult = 25 | 3; alert(iResult); //輸出 "27"

    25 和 3 進(jìn)行 OR 運(yùn)算的結(jié)果是 27:

    25 = 0000 0000 0000 0000 0000 0000 0001 10013 = 0000 0000 0000 0000 0000 0000 0000 0011 -------------------------------------------- OR = 0000 0000 0000 0000 0000 0000 0001 1011

    可以看出,在兩個(gè)數(shù)字中,共有 4 個(gè)數(shù)位存放的是 1,這些數(shù)位被傳遞給結(jié)果。二進(jìn)制代碼 11011 等于 27。

    位運(yùn)算 XOR

    位運(yùn)算 XOR 由符號(hào)(^)表示,當(dāng)然,也是直接對(duì)二進(jìn)制形式進(jìn)行運(yùn)算。XOR 不同于 OR,當(dāng)只有一個(gè)數(shù)位存放的是 1 時(shí),它才返回 1。真值表如下:

    第一個(gè)數(shù)字中的數(shù)位第二個(gè)數(shù)字中的數(shù)位結(jié)果
    110
    101
    011
    000

    對(duì) 25 和 3 進(jìn)行 XOR 運(yùn)算,代碼如下:

    var iResult = 25 ^ 3; alert(iResult); //輸出 "26"

    25 和 3 進(jìn)行 XOR 運(yùn)算的結(jié)果是 26:

    25 = 0000 0000 0000 0000 0000 0000 0001 10013 = 0000 0000 0000 0000 0000 0000 0000 0011 --------------------------------------------- XOR = 0000 0000 0000 0000 0000 0000 0001 1010

    可以看出,在兩個(gè)數(shù)字中,共有 4 個(gè)數(shù)位存放的是 1,這些數(shù)位被傳遞給結(jié)果。二進(jìn)制代碼 11010 等于 26。

    左移運(yùn)算

    左移運(yùn)算由兩個(gè)小于號(hào)表示(<<)。它把數(shù)字中的所有數(shù)位向左移動(dòng)指定的數(shù)量。例如,把數(shù)字 2(等于二進(jìn)制中的 10)左移 5 位,結(jié)果為 64(等于二進(jìn)制中的 1000000):

    var iOld = 2; //等于二進(jìn)制 10 var iNew = iOld << 5; //等于二進(jìn)制 1000000 十進(jìn)制 64

    注意:在左移數(shù)位時(shí),數(shù)字右邊多出 5 個(gè)空位。左移運(yùn)算用 0 填充這些空位,使結(jié)果成為完整的 32 位數(shù)字。

    注意:左移運(yùn)算保留數(shù)字的符號(hào)位。例如,如果把 -2 左移 5 位,得到的是 -64,而不是 64?!胺?hào)仍然存儲(chǔ)在第 32 位中嗎?”是的,不過(guò)這在 ECMAScript 后臺(tái)進(jìn)行,開(kāi)發(fā)者不能直接訪(fǎng)問(wèn)第 32 個(gè)數(shù)位。即使輸出二進(jìn)制字符串形式的負(fù)數(shù),顯示的也是負(fù)號(hào)形式(例如,-2 將顯示 -10。)

    有符號(hào)右移運(yùn)算

    有符號(hào)右移運(yùn)算符由兩個(gè)大于號(hào)表示(>>)。它把 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ù)字,如下圖所示:

    無(wú)符號(hào)右移運(yùn)算

    無(wú)符號(hào)右移運(yùn)算符由三個(gè)大于號(hào)(>>>)表示,它將無(wú)符號(hào) 32 位數(shù)的所有數(shù)位整體右移。對(duì)于正數(shù),無(wú)符號(hào)右移運(yùn)算的結(jié)果與有符號(hào)右移運(yùn)算一樣。

    用有符號(hào)右移運(yùn)算中的例子,把 64 右移 5 位,將變?yōu)?2:

    var iOld = 64; //等于二進(jìn)制 1000000 var iNew = iOld >>> 5; //等于二進(jìn)制 10 十進(jìn)制 2

    對(duì)于負(fù)數(shù),情況就不同了。

    無(wú)符號(hào)右移運(yùn)算用 0 填充所有空位。對(duì)于正數(shù),這與有符號(hào)右移運(yùn)算的操作一樣,而負(fù)數(shù)則被作為正數(shù)來(lái)處理。

    由于無(wú)符號(hào)右移運(yùn)算的結(jié)果是一個(gè) 32 位的正數(shù),所以負(fù)數(shù)的無(wú)符號(hào)右移運(yùn)算得到的總是一個(gè)非常大的數(shù)字。例如,如果把 -64 右移 5 位,將得到 134217726。如何得到這種結(jié)果的呢?

    要實(shí)現(xiàn)這一點(diǎn),需要把這個(gè)數(shù)字轉(zhuǎn)換成無(wú)符號(hào)的等價(jià)形式(盡管該數(shù)字本身還是有符號(hào)的),可以通過(guò)以下代碼獲得這種形式:

    var iUnsigned64 = -64 >>> 0;

    然后,用 Number 類(lèi)型的 toString() 獲取它的真正的位表示,采用的基為 2:

    alert(iUnsigned64.toString(2));

    這將生成 11111111111111111111111111000000,即有符號(hào)整數(shù) -64 的二進(jìn)制補(bǔ)碼表示,不過(guò)它等于無(wú)符號(hào)整數(shù) 4294967232。

    出于這種原因,使用無(wú)符號(hào)右移運(yùn)算符要小心。

    總結(jié)

    以上是生活随笔為你收集整理的js 位运算的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。