tft每日頭條

 > 圖文

 > 浮點數的定義

浮點數的定義

圖文 更新时间:2024-07-30 10:20:19

微信搜索關注「水滴與銀彈」公衆号,第一時間獲取優質技術幹貨。7年資深後端研發,用簡單的方式把技術講清楚。

在上一篇文章中,我們主要介紹了在計算機中使用定點數表示數字的方式。

簡單回顧一下,簡單來說,用定點數表示數字時,會約定小數點的位置固定不變,整數部分和小數部分分别轉換為二進制,就是定點數的結果。

但用定點數表示小數時,存在數值範圍、精度範圍有限的缺點,所以在計算機中,我們一般使用「浮點數」來表示小數。

這篇文章,我們就來詳細看一下浮點數到底是如何表示小數的,以及浮點數的的範圍和精度有多大。

什麼是浮點數?

首先,我們需要理解什麼是浮點數?

之前我們學習了定點數,其中「定點」指的是約定小數點位置固定不變。那浮點數的「浮點」就是指,其小數點的位置是可以是漂浮不定的。

這怎麼理解呢?

其實,浮點數是采用科學計數法的方式來表示的,例如十進制小數 8.345,用科學計數法表示,可以有多種方式:

8.345=8.345*10^0 8.345=83.45*10^-1 8.345=834.5*10^-2 ...

看到了嗎?用這種科學計數法的方式表示小數時,小數點的位置就變得「漂浮不定」了,這就是相對于定點數,浮點數名字的由來。

使用同樣的規則,對于二進制數,我們也可以用科學計數法表示,也就是說把基數 10 換成 2 即可。

浮點數如何表示數字?

我們已經知道,浮點數是采用科學計數法來表示一個數字的,它的格式可以寫成這樣:

V=(-1)^S*M*R^E

其中各個變量的含義如下:

  • S:符号位,取值 0 或 1,決定一個數字的符号,0 表示正,1 表示負
  • M:尾數,用小數表示,例如前面所看到的 8.345 * 10^0,8.345 就是尾數
  • R:基數,表示十進制數 R 就是 10,表示二進制數 R 就是 2
  • E:指數,用整數表示,例如前面看到的 10^-1,-1 即是指數
  • 如果我們要在計算機中,用浮點數表示一個數字,隻需要确認這幾個變量即可。

    假設現在我們用 32 bit 表示一個浮點數,把以上變量按照一定規則,填充到這些 bit 上就可以了:

    浮點數的定義(什麼是浮點數)1

    假設我們定義如下規則來填充這些 bit:

  • 符号位 S 占 1 bit
  • 指數 E 占 10 bit
  • 尾數 M 占 21 bit
  • 按照這個規則,将十進制數 25.125 轉換為浮點數,轉換過程就是這樣的(D代表十進制,B代表二進制):

    1. 整數部分:25(D) = 11001(B)
    2. 小數部分:0.125(D) = 0.001(B)
    3. 用二進制科學計數法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)

    所以符号位 S = 0,尾數 M = 1.001001(B),指數 E = 4(D) = 100(B)。

    按照上面定義的規則,填充到 32 bit 上,就是這樣:

    浮點數的定義(什麼是浮點數)2

    浮點數的結果就出來了,是不是很簡單?

    但這裡有個問題,我們剛才定義的規則,符号位 S 占 1 bit,指數位 E 占 10 bit,尾數 M 占 21 bit,這個規則是我們拍腦袋随便定義出來的。

    如果你也想定一個新規則,例如符号位 S 占 1 bit,指數位 E 這次占 5 bit,尾數 M 占 25 bit,是否也可以?當然可以。

    按這個規則來,那浮點數表示出來就是這樣:

    浮點數的定義(什麼是浮點數)3

    我們可以看到,指數和尾數分配的位數不同,會産生以下情況:

    1. 指數位越多,尾數位則越少,其表示的範圍越大,但精度就會變差,反之,指數位越少,尾數位則越多,表示的範圍越小,但精度就會變好
    2. 一個數字的浮點數格式,會因為定義的規則不同,得到的結果也不同,表示的範圍和精度也有差異

    早期人們提出浮點數定義時,就是這樣的情況,當時有很多計算機廠商,例如IBM、微軟等,每個計算機廠商會定義自己的浮點數規則,不同廠商對同一個數表示出的浮點數是不一樣的。

    這就會導緻,一個程序在不同廠商下的計算機中做浮點數運算時,需要先轉換成這個廠商規定的浮點數格式,才能再計算,這也必然加重了計算的成本。

    那怎麼解決這個問題呢?業界迫切需要一個統一的浮點數标準。

    浮點數标準

    直到1985年,IEEE 組織推出了浮點數标準,就是我們經常聽到的 IEEE754 浮點數标準,這個标準統一了浮點數的表示形式,并提供了 2 種浮點格式:

  • 單精度浮點數 float:32 位,符号位 S 占 1 bit,指數 E 占 8 bit,尾數 M 占 23 bit
  • 雙精度浮點數 float:64 位,符号位 S 占 1 bit,指數 E 占 11 bit,尾數 M 占 52 bit
  • 為了使其表示的數字範圍、精度最大化,浮點數标準還對指數和尾數進行了規定:

    1. 尾數 M 的第一位總是 1(因為 1 <= M < 2),因此這個 1 可以省略不寫,它是個隐藏位,這樣單精度 23 位尾數可以表示了 24 位有效數字,雙精度 52 位尾數可以表示 53 位有效數字
    2. 指數 E 是個無符号整數,表示 float 時,一共占 8 bit,所以它的取值範圍為 0 ~ 255。但因為指數可以是負的,所以規定在存入 E 時在它原本的值加上一個中間數 127,這樣 E 的取值範圍為 -127 ~ 128。表示 double 時,一共占 11 bit,存入 E 時加上中間數 1023,這樣取值範圍為 -1023 ~ 1024。

    除了規定尾數和指數位,還做了以下規定:

  • 指數 E 非全 0 且非全 1:規格化數字,按上面的規則正常計算
  • 指數 E 全 0,尾數非 0:非規格化數,尾數隐藏位不再是 1,而是 0(M = 0.xxxxx),這樣可以表示 0 和很小的數
  • 指數 E 全 1,尾數全 0:正無窮大/負無窮大(正負取決于 S 符号位)
  • 指數 E 全 1,尾數非 0:NaN(Not a Number)
  • 浮點數的定義(什麼是浮點數)4

    标準浮點數的表示

    有了這個統一的浮點數标準,我們再把 25.125 轉換為标準的 float 浮點數:

    1. 整數部分:25(D) = 11001(B)
    2. 小數部分:0.125(D) = 0.001(B)
    3. 用二進制科學計數法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)

    所以 S = 0,尾數 M = 1.001001 = 001001(去掉1,隐藏位),指數 E = 4 127(中間數) = 135(D) = 10000111(B)。填充到 32 bit 中,如下:

    浮點數的定義(什麼是浮點數)5

    這就是标準 32 位浮點數的結果。

    如果用 double 表示,和這個規則類似,指數位 E 用 11 bit 填充,尾數位 M 用 52 bit 填充即可。

    浮點數為什麼有精度損失?

    我們再來看一下,平時經常聽到的浮點數會有精度損失的情況是怎麼回事?

    如果我們現在想用浮點數表示 0.2,它的結果會是多少呢?

    0.2 轉換為二進制數的過程為,不斷乘以 2,直到不存在小數為止,在這個計算過程中,得到的整數部分從上到下排列就是二進制的結果。

    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.2(D) = 0.00110...(B)。

    因為十進制的 0.2 無法精确轉換成二進制小數,而計算機在表示一個數字時,寬度是有限的,無限循環的小數存儲在計算機時,隻能被截斷,所以就會導緻小數精度發生損失的情況。

    浮點數的範圍和精度有多大?

    最後,我們再來看一下,用浮點數表示一個數字,其範圍和精度能有多大?

    以單精度浮點數 float 為例,它能表示的最大二進制數為 1.1.11111...1 * 2^127(小數點後23個1),而二進制 1.11111...1 ≈ 2,所以 float 能表示的最大數為 2^128 = 3.4 * 10^38,即 float 的表示範圍為:-3.4 * 10^38 ~ 3.4 * 10 ^38。

    它能表示的精度有多小呢?

    float 能表示的最小二進制數為 0.0000....1(小數點後22個0,1個1),用十進制數表示就是 1/2^23。

    用同樣的方法可以算出,double 能表示的最大二進制數為 1.111...111(小數點後52個1) * 2^1023 ≈ 2^1024 = 1.79 * 10^308,所以 double 能表示範圍為:-1.79 * 10^308 ~ 1.79 * 10^308。

    double 的最小精度為:0.0000...1(51個0,1個1),用十進制表示就是 1/2^52。

    從這裡可以看出,雖然浮點數的範圍和精度也有限,但其範圍和精度都已非常之大,所以在計算機中,對于小數的表示我們通常會使用浮點數來存儲。

    總結

    這篇文章我們主要講了數字的浮點數表示方式,總結如下:

    1. 浮點數一般用科學計數法表示
    2. 把科學計數法中的變量,填充到固定 bit 中,即是浮點數的結果
    3. 在浮點數提出的早期,各個計算機廠商各自制定自己的浮點數規則,導緻不同廠商對于同一個數字的浮點數表示各不相同,在計算時還需要先進行轉換才能進行計算
    4. 後來 IEEE 組織提出了浮點數的标準,統一了浮點數的格式,并規定了單精度浮點數 float 和雙精度浮點數 double,從此以後各個計算機廠商統一了浮點數的格式,一直延續至今
    5. 浮點數在表示小數時,由于十進制小數在轉換為二進制時,存在無法精确轉換的情況,而在固定 bit 的計算機中存儲時會被截斷,所以浮點數表示小數可能存在精度損失
    6. 浮點數在表示一個數字時,其範圍和精度非常大,所以我們平時使用的小數,在計算機中通常用浮點數來存儲

    微信搜索關注「水滴與銀彈」公衆号,第一時間獲取優質技術幹貨。7年資深後端研發,用簡單的方式把技術講清楚。

    ,

    更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

    查看全部

    相关圖文资讯推荐

    热门圖文资讯推荐

    网友关注

    Copyright 2023-2024 - www.tftnews.com All Rights Reserved