最近重新看了一篇《深入理解計算機系統》,果然好書讀多少次都能得到新的知識。關於浮點運算ieee754上次讀過還只是蜻蜓點水,完全沒有深入理解,這次結合p.j.plauger寫的《c標準庫》對該標準在計算機中是如何實現的有了更深入的了解。下面我記錄下我最近閱讀內容及個人的思考理解。
符號 s=1這個數為負s=0則為正;
尾數 m是乙個二進位制小數,它值域是1~2-epsilon(小的數)或是0~1-epsilon;
階碼 e是對浮點數加權;
下面是通常的單精度float和雙精度double儲存格式,單精度是4個位元組,雙精度是8個位元組
現在對單精度編碼進行講解,理解了單精度,對於雙精度只是字段長度的改變而已。
對上圖單精度的s,exp和frac欄位分別是1位,k=8位和n=23位。
根據exp的值,浮點精可以被編碼三種不同的情況,分別是:
1.規格化 exp≠0和≠255 即exp欄位不是全為0也不是全為1;
2.非規格化 exp=0 exp欄位全為0;
3a.無窮大 exp=255並且frac=0
3b.nan(不是乙個數)exp=255並且frac≠0
對規格化:階碼e=e-bias,e為exp欄位無符號數的值,bias=2^(k-1)-1=2^(8-1)-1=127,尾數m=1+f,f是frac欄位的二進位制小數,所以
對非規格化:階碼e=1-bias=-126(這有點違反直覺,正常覺得應該是-bias,設計者這樣設定是為了非規格化平滑過渡到規格化,因為規格化最小值是2^-126),尾數m=f,所以
以上就是ieee754浮點數編碼的格式,然而如果你開啟一般的c編譯器的標頭檔案float.h,會發現實現標準庫設計者寫的**跟上面的編碼有點出入,但如果你再仔細看其實又沒什麼問題。
在float.h中會看見很多巨集定義例如flt_*,dbl_*,ldbl_*。這裡flt表示單精度float,dbl表示雙精度double,ldbl為long double。
我就對flt_的巨集進行說明。
flt_rounds 表示浮點加法捨入模式由它的值確定(-1表示不能確定 0表示向0捨入 1表示最近捨入 2表示向正無窮捨入 3表示向負無窮捨入)
flt_radix表示指數表示的基數 其值為2
flt_mant_dig表示flt_radix進製的浮點數有效位數p 這裡規格化浮點數它有23個小數字1個整數字一共24位,所以其值為24
flt_dig表示10進製的精確位數 log10(2^23)=6 單精度其10進製精確是6~7位6是完全精確的
你可以改變浮點數看輸出,其位數精確6~7位。
flt_min_exp表示二進位制最小指數值等於-125 在上的浮點編碼我們應該知道階碼應該是-126~127而這裡最小值怎麼是-125,因為庫的設計者是將尾數都化為小數部分,所以階碼相應加了1
flt_min_10_exp表示10進製最小指數值為-37 log10(2^-125)=-37
flt_max_exp表示二進位制最大指數值等於127+1=128
flt_max_10_exp表示10進製最大指數值log10((1-2^-24)x2^128)=38
flt_epsilon表示1和給定浮點型別比1大的最小值之差=2^-23=1.19209290e-07f
其它一些巨集定義就是最大最小之類,通過了理解了編碼可以計算下與之對照
浮點數的運算原理 IEEE 754
ieee二進位制浮點數算術標準 ieee 754 是20世紀80年代以來最廣泛使用的浮點數運算標準,為許多cpu與浮點運算器所採用。ieee 754規定了四種表示浮點數值的方式 單精確度 32位 雙精確度 64位 延伸單精確度 43位元以上,很少使用 與延伸雙精確度 79位元以上,通常以80位元實做...
IEEE 754浮點型儲存方式
最近突然糾結與浮點型到底是怎麼儲存的,看了很多理論描述,以為沒有找到特別詳細的例子,還是一臉懵逼。所以我特意記錄一下浮點型變數儲存方式的例子。以最常用的ieee 754標準為例,單精度浮點型的二進位制主要分為三部分 數符 階數 尾數 階數也包含一位階符,但從儲存上看應該是三部分 公式為 數符x尾數x...
單精度浮點數(IEEE754)
單精度浮點數佔據4個位元組,4個位元組的分配如下 a 第一位為符號位,0表示正,1表示負 b 第2 9位為階碼,採用移碼表示 c 第10 32位為尾數,採用原碼表示。1 給定32位串,如何轉換成十進位制數 假設記憶體中存在32位串 cd cc 08 41。因為intel cpu採用little en...