浮點數在計算機底層的表示及運算

tsewell發表於2020-07-07

1.浮點數在計算機底層儲存機制

單精度浮點數float佔4位元組32位,雙精度浮點數double佔8位元組64位。float和double的二進位制儲存結構都是:符號位+指數位+尾數位

  • 符號位:表示浮點數的正負,0:正 1:負
  • 指數位:控制浮點數數值的大小
  • 尾數位:控制浮點數的精度

float32的位數

符號位 指數位 尾數位
1 8 23

float64的位數

符號位 指數位 尾數位
1 11 52

比如我們要把float32的6.125轉化為 二進位制的表示

  1. 符號位 正數為0,負數為1,所以6.125的符號位為 1
  2. 指數位 首先把6.125轉成二進位制的小數.
  • 整數部分 5 轉二進位制等於 110
  • 小數部分乘以2取整,然後正序排列
0.125 * 2     0
0.25 * 2      0
0.5 * 2       1

小數部分等於101, 結果為110.001 科學計數法表示 1.10001 * 2^2,所以指數為2,由於指數也分正負 2^8 範圍是-127 ~ 128 正數需要 + 127 指數位等於127+2 = 129 轉化為二進位制為 10000001

  1. 尾數位 1.10001 小數點前面的是隱藏位不需要 後面補齊 所以尾數位為 10001000000000000000000

  2. 最終6.125的二進位制表示為 01000000110001000000000000000000

2.浮點數的計算機底層加法運算過程

我們都知道float64 中 0.1 + 0.2 != 0.3 那麼就來看一下浮點數計算的過程

  1. 首先把0.1和0.2 分別轉換成二進位制表示為
0.1 0(符號位) 01111111011(指數位) 1001100110011001100110011001100110011001100110011010(尾數位)

0.2 0(符號位) 01111111100(指數位) 1001100110011001100110011001100110011001100110011010(尾數位)
  1. 指數位對階:一般是用小的指數減去大的 01111111011 - 01111111100 = -1 所以0.1 的尾數位右移一位 (tips:浮點數尾數位隱藏位預設是1)

0.1 尾數位 1.1001100110011001100110011001100110011001100110011010 右移一位

得到 0.1100110011001100110011001100110011001100110011001101(0)

按照01, 0捨去,所以得到

0.1100110011001100110011001100110011001100110011001101

0.10.2 的尾數相加得到

1.1001100110011001100110011001100110011001100110011010

0.1100110011001100110011001100110011001100110011001101

10.0110011001100110011001100110011001100110011001100111
  1. 正規化 根據正規化要求,我們把結果右移一位,並且指數位+1

1.0011001100110011001100110011001100110011001100110011(1)1

1.0011001100110011001100110011001100110011001100110100
  1. 最後得到的二進位制為

0 01111111101 0011001100110011001100110011001100110011001100110100

轉化十進位制

0.30000000000000004

所以現在知道為什麼 0.1 + 0.2 != 0.3 了吧

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章