天天看點

二進制轉換 html,JavaScript中的二進制數

計算機中是用二進制數來存儲計算的,在我們學習計算機程式設計語言是總會遇到二進制數的計算,本文就來為大家介紹一下JavaScript中的二進制數,希望對大家有一定的幫助。

二進制轉換 html,JavaScript中的二進制數

在本文中你将學到如下知識:二進制數的表示

js中的二進制數整數

js中的位運算

二進制數

本文假設你知道計算機中用二進制數來存儲,計算數字,并且熟悉二進制數的表示方法。

為了實作不同的目的,其實都是為了簡化問題,二進制數在計算機中有不同的表示方法,如原碼、反碼、補碼和移碼等。

注意:本文問了簡化運算,二進制數都是用一個位元組——8個二進制位來簡化說明

先來說說真值吧,我們表示自然數包括正數,負數和0,下面是1和-1的二進制表示,我們稱為真值+ 00000001 # +1

- 00000001 # -1

8位二進制數能表示的真值範圍是[-2^8, +2^8]。

由于計算機隻能存儲0和1,不能存儲正負,是以用8個二進制位的最高位來表示符号,0表示正,1表示負,用後七位來表示真值的絕對值,這種表示方法稱為原碼表示法,簡稱原碼,上面的1和-1的原碼如下:0 0000001 # +1

1 0000001 # -1

由于10000000的意思是-0,這個沒有意義,所有這個數字被用來表示-128,所有負數就比整數多一個。

由于最高位被用來表示符号了,現在能表示的範圍是[-2^7, +2^7-1],即[-128, +127]

反碼是另一種表示數字的方法,其規則是整數的反碼何其原碼一樣,負數的反碼将其原碼的符号位不變,其餘各位按位取反0 0000001 # +1

1 1111110 # -1

反碼的表示範圍是[-2^7, +2^7-1],即[-128, +127]

補碼是另外一種表示方法,主要是為了簡化運算,将減法變為加法而發明的數字表示法,其規則是整數的補碼和原碼一樣,負數的補碼是其反碼末尾加10 0000001 # +1

1 1111111 # -1

快速計算負數補碼的規則就是,由其原碼低位向高位找到第一個1,1和其低位不變,1前面的高位按位取反即可,不知道聰明的你能不能想到原理。

8位補碼表示的範圍是[-2^7, +2^7-1],即[-128, +127]

js中的二進制數整數

再來說說js中的二進制整數表示,一名合格的jser應該支援在js中隻有一種數字類型,就是浮點型,js的浮點數遵循IEEE 754規範。

然而在js中還有另一種類型的資料,那就是用32個比特位表示的整數,隻要對js中的任何數字做位運算作業系統内部都會将其轉換成整形,嘗試在控制台輸入下面的代碼2.1 | 0 # 或運算

>>> 2

js中的這種整形是區分正負數的,我們根據上面的知識推斷js中的整數的表示範圍是[-2^31, +2^31-1],即[-2147483648, +2147483647],在控制台輸出下面的代碼來驗證我們的推斷。-2147483648 | 0

>>> -2147483648

-2147483649 | 0

>>> 2147483647

2147483647 | 0

>>> 2147483647

2147483648 | 0

>>> -2147483648

從上面的結果可以看出,大于和小于最低和最高的值再去進行轉換時都将改變正負号

js中的位運算

js中的位運算符有下面這些,對數字進行這些操作時,系統内部都會講64的浮點數轉換成32位的整形& 與

| 或

~ 非

^ 異或

<< 左移

>> 算數右移(有符号右移)

>>> 邏輯右移(無符号右移)

下面舉例子來說明每個運算符的作用,開始之前先來介紹幾個會用到的知識點

原生二進制字面量

es6中引入了原生二進制字面量,二進制數的文法是0b開頭,我們将會用到這個新功能,目前chrome最新版已經支援。0b111 // 7

0b001 // 1

Number.prototype.toString

先來介紹下下面會用到的一個方法——Number.prototype.toString方法可以講數字轉化為字元串,有一個可選的參數,用來決定将數字顯示為指定的進制,下面可以檢視3的二進制表示3..toString(2)

>> 11

& 與

&按位與會将操作數和被操作數的相同為進行與運算,如果都為1則為1,如果有一個為0則為0101

011

---

001

101和011與完的結果就是001,下面在js中進行驗證(0b101 & 0b011).toString(2)

>>> "1"

| 或

|按位或是相同的位置上隻要有一個為1就是1,兩個都為0則為0

101

001

---

101

101和001或完的結果是101,下面在js中進行驗證(0b101 | 0b001).toString(2)

>>> "101"

~ 非

~操作符會将操作數的每一位取反,如果是1則變為0,如果是0則邊為1101

---

010

101按位非的結果是010,下面在js中驗證(~0b101).toString(2)

>>> "-110"

啊呀,怎麼結果不對呢!!!上面提到了js中的數字是有符号的,我們忘記了最高位的符号了,為了簡化我們将32位簡化為8位,注意最高位是符号位0 0000101

1 1111010 // 非後的結果

1 0000101 // 求反

1 0000110 // 求補

1 1111010明顯是一個負數,而且是負數的補碼表示,我們的求它的原碼,也就是再對它求補1 0000110就是這個數的真值,也就是結果顯示-110,這下總算自圓其說了,O(∩_∩)O哈哈~

其實上面的與和或也都是會操作符号位的,不信你試試下面這兩個,可以看到符号位都參與了運算(0b1&-0b1)

>>> 1

(0b1|-0b1)

>>> -1

^ 異或

再來說說異或,這個比較有意思,異或顧名思義看看兩個位是否為異——不同,兩個位不同則為1,兩個位相同則為0101

001

---

100

101和001異或的結果是100,js中驗證(0b101^0b001).toString(2)

>>> "100"

<< 左移

左移的規則就是每一位都向左移動一位,末尾補0,其效果相當于×2,其實計算機就是用移位操作來計算乘法的010

---

0100

010左移一位就會變為100,下面在js中驗證(0b010<<1).toString(2)

>>> "100"

>> 算數右移(有符号右移)

算數右移也稱為有符号右移,也就是移位的時候高位補的是其符号位,整數則補0,負數則補1(0b111>>1).toString(2)

>>> "11"

(-0b111>>1).toString(2)

>>> "-100"

負數的結果好像不太對勁,我們來看看是怎麼回事-111 // 真值

1 0000111 // 原碼

1 1111001 // 補碼

1 1111100 // 算數右移

1 0000100 // 移位後的原碼

-100 // 移位後的真值

>>> 邏輯右移(無符号右移)

邏輯右移又稱為無符号右移,也就是右移的時候高位始終補0,對于整數和算數右移沒有差別(0b111>>>1).toString(2)

>>> "11"

對于負數則就不同了,右移後會變為正數(-0b111>>>1).toString(2)

>>> "1111111111111111111111111111100"

關于開頭的問題

關于二進制數就說這麼多吧,再來說說開頭的問題,開頭的問題其實可以分解為下面的問題因為search會傳回-1 和找到位置的索引,也就成了下面的問題!~-1

>>> ture

!~0

>>> false

!~1

>>> false

非運算對于數字的結果相當于改變符号,并對其值的絕對值-1~-1

>>> 0

~0

>>> -1

~1

>>> -2

其實可以看出!~x的邏輯就是判斷x是否為-1,my god這邏輯真是逆天了,我還是勸大家直接寫成 x === -1多好啊

本文轉自:https://yanhaijing.com/javascript/2016/07/20/binary-in-js/