你知道 0.1+0.2 !==0.3是進位制問題,但你講不出個所以然,是吧??

Sunshine_Lin發表於2021-12-20

前言

大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心。有一個問題困擾了廣大前端工程師,那就是 0.1 + 0.2 !== 0.3

截圖2021-12-13 下午10.25.39.png

大家可能都知道,這是因為計算機在儲存數字是是通過 二進位制 來儲存的,呈現的時候是通過 十進位制 來儲存的,所以有誤差。但是再繼續深問你為啥計算機的 二進位制 儲存會造成誤差呢,可能你就支支吾吾了。。。

image.png

十進位制轉二進位制

我們們先來講講十進位制轉二進位制是怎麼轉的吧。。情況有三種:

  • 1、整數
  • 2、負整數
  • 3、小數

整數

整數的十進位制轉二進位制,是怎麼轉的呢?記住一條公式:除二取餘,然後倒序排列,高位補零。啥意思呢?別急,我給你講講哈,我就拿 81 這個數字來舉例子吧,畢竟曾經有一個男人,單場砍下 81分

截圖2021-12-14 下午9.09.21.png
可以得出 1000101 ,可以看出有7位,但是呢,計算機內部表示數是定長的,例如 8位、16位、32位 ,所以7位是不夠的,需要 高位補0 ,也就是 01000101 ,規範寫法為 (81)10 = (01000101)

截圖2021-12-14 下午9.11.07.png

負整數

負整數的話,是這樣的規則:

  • 第一步:把正整數轉成二進位制
  • 第二步:對二進位制取反
  • 第三步:對取反後的二進位制進行加1

截圖2021-12-14 下午9.13.02.png

小數

小數轉二進位制的話是這樣的:對小數點以後的數乘以2,得出結果,取結果的整數部分(不是 0 就是 1),然後再對結果的小數點以後的數乘以2,得出結果,再取結果整數部分,再然後然後再對結果的小數點以後的數乘以2。。。。以此類推。。知道小數部分為0或者位數已經到達位數。再把這個過程中取的整數按先後順序排好就行了。

我舉個例子吧,比如 0.125

截圖2021-12-13 下午10.07.07.png

我再舉個例子,比如 121.6

截圖2021-12-14 下午9.15.01.png

0.1 + 0.2

再回到 0.1 + 0.2 這個問題

截圖2021-12-13 下午10.23.42.png

可以看到,0.1和0.2轉成二進位制都是無限迴圈的,超過了 52位 ,所以儲存時只能通過近似值去儲存他們兩,那自然的,當 0.1 + 0.2 時,近似值轉十進位制肯定也是近似值,所以造成誤差

截圖2021-12-13 下午10.25.39.png

結語

我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那我們們可以交朋友,一起摸魚哈哈,摸魚群
image.png

相關文章