浮點數的基本認知

2022-10-09 07:21:11 字數 2311 閱讀 9189

8.355 = 8.355 *10 ^0

8.355 = 83.55 *10 ^-1

8.355 = 835.5 *10 ^-2

8.355 = 8355 *10 ^-3

83550000000 = 8.355 *10 ^10

計算機中的表達:

8.355 === 8.355e0

8.355 === 83.55e-1

8.355 === 835.5e-2

8.355 === 8355e-3

83550000000 === 8.355e10

順理成章的我們將以上的科學計數法總結出乙個通用表示式:v = (-1)^s * m * r^es:符號位,取值 0 或 1,決定乙個數字的符號,0 表示正,1 表示負。

m:尾數,用小數表示,例如前面所看到的 8.355 * 10^0,8.355 就是尾數

r:基數,表示十進位制數 r 就是 10,表示二進位制數 r 就是 2

e:指數,用整數表示,例如前面看到的 10^-1,-1 即是指數

接下來我們自定義一些規則,看看如何在32bit中表示乙個浮點數。

如圖所示,我們定義如下規則:

現在我們將12.125轉換為32bit浮點數。

整數:12(d) = 110(b)

小數:0.125(b)) = 0.001(b)

所以:110.001(b) = 12.125(d) = 1.10001 *2 ^2(b)

按自定義規則排列得到:0 1100000000 110001000000000000000

注意:以上得到的結果不是標準的浮點數排列,而是為了舉例子自定義的。

當我們指定的指數字數越大時,浮點數的範圍就越大,反之越小。而尾數尾數越大時浮點數精度就越高,反之精度就越低。

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

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

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

直到2023年,ieee組織推出了浮點數標準,就是我們經常聽到的ieee754浮點數標準,這個標準統一了浮點數的表示形式,並提供了 2 種浮點格式:

為了使其表示的數字範圍、精度最大化,浮點數標準還對指數和尾數進行了規定:

針對特定情況,還有以下規定:

回到開篇的例子,我們用統一標準將12.125轉換為32bit浮點數看看。

整數:12(d) = 110(b)

小數:0.125(b)) = 0.001(b)

所以:110.001(b) = 12.125(d) = 1.10001 *2 ^2(b)

指數:2 + 127 = 129(d) = 10000001(b)

按統一標準排列得到:0 10000001 10001000000000000000000

浮點數在計算機中存在精度損失。

用「乘二取整,順序排列」的方法計算 0.2(d) 的二進位制數。

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.00110011...(b)

由於尾數的尾數限制,0.00110011...(b)只會取到限定的位數。這樣就導致了尾數精度的損失。

單精度浮點數:0.00000000000000000000001(b) => (1/2)^23(d)

同理,雙精度浮點數:(1/2)^52(d)

單精度浮點數:最大範圍1.111...111 *2 ^127(b) ~= 2 ^128(d) ~= 3.4 *10 ^38, 最小範圍則是在最大範圍前面加上負號即可-3.4 *10 ^38

同理,雙精度浮點數:-2 ^1024 ~= -1.79 *10 ^3081.79 *10 ^308

浮點數的儲存以及 浮點數的比較

浮點數的儲存採用的是近似的原理 float儲存格式為 s e m 1位符號位 8位指數 23位尾數 轉成數值即為 v 1 s 1.m 2 e 127 對於16.5轉成二進位制為00010000.1 1.00001 2 4,那麼在記憶體的表示為 符號位 指數4 127 131 尾數 0 1000001...

浮點數 儲存

關鍵字 體系結構 ieee754 浮點數 儲存 main 如果不執行上面的 讓我們來直接判斷,輸出的結果會是什麼?而在你執行程式之後,結果卻很讓人詫異 123.456001。為什麼會是123.456001?有六位小數可以理解,最後那個1是為何?有很多人解釋說最後那個1是亂碼,隨機的。嘿嘿 其實無論你...

浮點數操作

float fx 49.03f int nx fx 100 printf d nx 執行上述 結果 4902。用vc6.0,2005,gcc編譯執行結果都是一樣。為什麼會這樣呢,是因為浮點數運算具有不精確性。其實編譯上面的 編譯器會有警告的。warning c4244 initializing co...