js 的 二進制


1. 整數

例如十進制的 30

30/2  .......... 0

15/2 ............ 1

 7/2 ............ 1

3/2 .............. 1

1/2 .............. 1

所以得到結果是 從下往上,倒着排 11110 就是二進制的 30

 

2. 小數

例如十進制的 0.125

0.125*2=0.25 ............. 0

0.25*2=0.5 ............. 0

0.5*2=1 ............. 1

所以得到結果是 從上往下,順着排 0.001 就是二進制的 0.125

 

3.為什么 0.1 + 0.2 !== 0.3 ?

因為 JS 采用了 IEEE 754 雙精度版本(64位), 只要采用了 IEEE 754 的語言都會有這個問題。

從上面我們看到,二進制的小數是怎么算的,而這種結果很可能會導致無限循環。

例如十進制的 0.1

0.1*2=0.2 .......... 0

0.2*2=0.4 .......... 0

0.4*2=0.8 .......... 0

0.8*2=1.6 .......... 1

0.6*2=1.2 .......... 1

0.2*2=0.4 .......... 0

。。。

所以得到結果是 從上往下,順着排 0.00011(0011不斷循環) 就是二進制的 0.1

因為我們不可能把 0.1 的無限循環都記錄下來,所以 0.1 在 JS 引擎里面被截取了前面的部分

因此 0.1 在 JS 引擎里面不再精確地表示 0.1 了。

同樣 0.2 也有或者這個問題,所以 2 個非精確的小數相加,也就得到一個非精確的小數了。

ps: 認真數了一下,JS 到小數點后第18位,就完全忽略了。

 

JS Number 類型的二進制組成

根據國際標准 IEEE 754,JavaScript 浮點數的64個二進制位,從最左邊開始,是這樣組成的。

  • 第1位:符號位,0表示正數,1表示負數
  • 第2位到第12位(共11位):指數部分 (表示 2^−1022~2^1023)
  • 第13位到第64位(共52位):小數部分(有效數字,可以到53位精度)

疑問1:為什么明明52位,為什么可以表示53位精度?

IEEE754規定小數部分第一位隱含為1,不寫,因為所有二進制第一個有效數字都是1。

所以加上省略的1位,精度位數是 53 bit。所以在 0 ~ 2^53 內的整數都是有效數字,算上第1位符號位,就可以得到 -2^53 ~ 2^53 都是有效數字

疑問2:為什么 11 位指數位,負數方向只能表示到 2^-1022 ,不能表示到 2^-1024 呢?

無論如何浮點數都滿足最左邊是 1。這就有一個嚴重問題:0沒有辦法被表示,因此指數為 -1023 時表示 0。

還有一種情況就是 Infinity,這種情況當指數是 -1024 時,表示無窮大


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM