浮點數筆記

關于浮點數問題相信大家早就耳濡目染了,但是為什么會出現這總情況呢?今天我們就來探究一下這個問題。


image.png

基礎復習

在探究這個問題之前,我們先復習一下計算機基礎的知識

  • 怎么將十進制浮點數轉化為二進制
  • 浮點數在計算機中如何存儲的
  • 計算機怎么計算加法
  • 計算機怎么計算減法

怎么將小數十進制轉化為二進制

計算方法:乘2取整的逆序(value*2 取整數,然后將小數繼續 * 2 ,直到結果為1.0,然后把整數逆序過來)
float.map((item)=> parseInt(item * 2)).revese()

小于1的浮點數

舉個例子:0.125
0.75 * 2 = 1.5 => 1
0.5 * 2 = 1.0 => 1
結果就是0.11

大于1的浮點數

大于1的浮點數需要兩步

  • 第一步:將整數部分轉換為二進制(輾轉相除法--除以進制數取余數然后逆序),這個較簡單這里不說
  • 第二步:將小數部分轉換為二進制(方法見上)
    例子:5.125
    第一步:整數轉二進制
    5/2 = 2···1
    2/2 = 1···0
    1/2 = 0···1
    所以整數部分就是101
    第二步:小數部分轉二進制
    0.125 * 2 = 0.25 => 0
    0.25 * 2 = 0.5 => 0
    0.5 * 2 = 1.0 => 1
    所以小數部分就是0.001

合起來 5.125 轉化為二進制為 101.001。下面已圖為證,在在線工具做的計算。

image.png

浮點數在計算機中的存儲方式

首先我們應該知道一般浮點數分為單精度和雙精度,比如在Java里面單精度用float來表示數據類型,而double來表示雙精度,可是何為單精度何為雙精度,單精度精度到多少,雙精度又精度到多少呢?當我們清楚了浮點數在計算機中怎么存儲的就明白了。

我們常說電腦的32位,64位跟這個就是有關系的。32位就是32個bit,8個bit等于一個byte(字節),那么32bit就是4個字節,也就是說用4個字節來存儲一個數,這就是單精度。而雙精度就是用64位,8個字節來存儲數,這就是雙精度。

那么精度是多少呢?

對于這個問題我們要知道計算機的二進制表示是遵循IEEE浮點數表示法。這種結構是一種科學計數法,用符號、指數和尾數來表示,底數定為2——即把一個浮點數表示為尾數乘以2的指數次方再添上符號。
下面是具體的規格:

占位 符號位 階碼 尾數 長度
float 1 8 23 32
double 1 11 52 64

在這里我們可以看到三個名詞:符號位、階碼、尾數

  • 符號位:用來表示正負(正數符號位為0,負數符號位為1)。
  • 階碼:階碼跟指數有很大的關系。另外一個相關名詞,階碼基數,單精度為127(01111111),雙精度為1023(01111111111)
  • 尾數:尾數其實就是精度了。所以單精度精確到小數點后23位,而雙精度精確到小數點后52位
單精度存儲方式

雙精度存儲方式

看到這里我相信應該已經有點感覺了,我再舉個例子,我相信應該就能明白了。

還是拿0.75來舉例吧,單精度簡單一下,以32為計算,64位同理。0.75的二進制是0.11,轉換為IEEE浮點數表示法為:1.1 * 2^-1。
我們還需要知道一點,階碼的值 = 階碼基數 + 指數 = 127 + (-1) = 126 ,拿到剛才那個網站計算一下,126 = 01111110


image.png

而1.1由于二進制整數部分都是1,所以去掉1留下0.1作為尾數部分(因為都是1點多的形式,所以這個1就沒必要存了),所以尾數部分就是 1000 0000 0000 0000 0000 000
加上符號位0.75在32位的表示為:0011 1111 0100 0000 0000 0000 0000 0000(粗體為指數部分,斜體為尾數部分)

計算機怎么計算加法

計算機怎么計算乘法

參考

為什么0.1 + 0.2不等于0.3?
浮點數在計算機中存儲方式

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。