【數據結構】定點數、浮點數是如何使用二進制實現的

Fist:why?

有時候只知道什麼還不夠,我們還需要爲什麼,所以我在整個數據結構系列中都要追尋這個答案。
Q1:爲什麼需要浮點型數據。
與整型數據一樣,小數應用也是十分廣泛,尤其是在高等數學方面。
由於計算機最初設計來就是爲了進行數學計算的,所以小數出現是理所當然的。

至於在計算機中爲什麼小數會分成兩類,等你看完這篇文章就明白了。

小數是如何使用二進制實現的

上一篇我們介紹了有符號無符號數在計算機低層如何表達。
1.整數類型之有符號、無符號數(原碼、反碼、補碼)詳解。
今天就講一下小數在計算機低層如何實現的。

1. 定點數

定點數是很早很早就出現的數據類型,幾乎在計算機出現沒多久就出現了。
其實這也是很符合歷史發展規律的,當人們找到合適的表達有符號數之後,
用定點數表達小數也是很理所應當的。

像有符號數一樣我們,人爲指定了一位數表達正負,定點數就是我們人爲的指定,二進制數字的一部分表示小數的整數部分、一部分表示小數的小數部分,這樣來表示小數。

小數點位固定在最後一位之後稱爲定點整數,小數點固定在最高位之後稱爲定點小數。

2. 浮點數

2.1科學記數法與浮點數

說到浮點數,我覺得使用科學記數法這樣來理解時最好的。
科學記數法例:+1.99714×10^13
由符號位,數值和冪數表示。其中冪數表明數字值的小數點往前或往後(當冪數爲正時)移動多少位。
浮點數也是這樣的的,採用科學記數法,實現小數點位置的浮動,這樣的大大增加了能表達的數字精確度,而且也能夠,更好的計算。

根據國際標準IEEE 754/854,任意一個二進制浮點數V可以表示成下面的形式:
V = (-1)^s ×M×2^E
(1)(-1)^s表示符號位,當s=0,V爲正數;當s=1,V爲負數。
(2)M表示有效數字,大於等於1,小於2。
(3)2^E表示指數位。

單精度浮點數格式
其中s:取值爲0,1。0爲正;
E爲有符號整數,取值爲 -126~+127;
M爲無符號整數,取值爲0-2^22,其實際值爲1.M(二進制);

也就是說單精度浮點數最大精度爲:
±1.00000000000000000000001 X 2^-126
轉換爲十進制數字是:
(1+2^-23) X (2^-126) = 1.401298 X 10^-45
但是:別看取值能取到10的負45次方,其實單精度浮點數的精度只有7位。
單精度浮點數的實際有效精度爲24位二進制,這相當於24*log102≈7.2位10進制的精度,所以平時我們說“單精度浮點數具有7位精度”

2.2浮點數的特殊數值

IEEE 標準指定了以下特殊值:±0、反向規格化的數、±∞ 和 NaN(如下表所示)。這些特殊值都是使用 emax+1 或 emin-1 的指數進行編碼的。

在這裏插入圖片描述

NaN:當指數段 exp 全爲 1 時,小數段爲非零時,結果值就被稱爲“NaN”(Not any Number),如圖 3 所示。
無窮:當指數段 exp 全爲 1,小數段全爲 0 時,得到的值表示無窮。當 s=0 時是 +∞,或者當 s=1 時是 -∞

2.3浮點數的舍入誤差

在浮點數的舍入問題上,IEEE 浮點格式定義了 4 種不同的舍入方式,如下表所示。其中,默認的舍入方法是向偶數舍入,而其他三種可用於計算上界和下界。
在這裏插入圖片描述
偶數舍入:四捨六入五成雙

這種約定的問題在於,人們可以很容易地想象
在這種情況下,舍入一組數據值將引入統計偏差
計算平均值。一組數字的平均值
我們用這種方法四捨五入的結果會略高於
數字本身。相反,如果我們總是把數字四捨五入到一半
從下到下,一組四捨五入數的平均值是
略低於數字本身的平均值。四捨五入
在現實生活中,偶數可以避免這種統計偏差。
它將在大約50%的時間內向上舍入,在大約50%的時間內向下舍入。

這是IEEE裏對偶數舍入的解釋百度翻譯。
就是舍入位的奇偶性決定是否進位。
例:10.0(10), 10.0(11), 10.1(10), 11.0(01)向偶數舍入(保留小數點後一位)的結果分別爲10.0, 10.1, 11.0, 11.0。
這樣是爲了避免統計偏差。

2.4不是總可靠的浮點數

正如我上面所講的,單精度浮點數取值能取到10的負45次方,但是由於其數值位只有24位,所以它的精度只有七位。

而且最重要的還有一點,在十進制轉換二進制計算的過程中會出現溢出的情況!
就是老師講課都說過的float不精確。這也是在一些編程過程中容易出現的問題,包括在數據庫等都會出現這個問題。
就像一個簡單的0.1使用二進制表示需要
0 01111011 10011001100110011001101

s=0 e=123 尾數部分的隱含位爲1 所以尾數是1.10011001100110011001101
以上二進制數據流對應的二進制數學運算表達式爲:
(-1)0*2123-1271.10011001100110011001101
即2^-4 X 1.10011001100110011001101
即2^23 X 1.10011001100110011001101 X 2^-27
即110011001100110011001101
2^-27
即13421773*2^-27
=0.100000001490116119384765625
與0.1誤差0.000000001490116119384765625
所以說並不精確,但是這個問題並不是不能解決的,在高級語言中都出現的特定的數據結構,來解決高精度數字,比如,java的BigDecimal,python的Decimal等等。
參考:IEEE 754浮點數標準詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章