[理工] IEEE 754 浮點數運算觀念問題
看板Grad-ProbAsk作者ayn775437403 (@@@@@@@@@@@@@@@@@@@)時間5年前 (2020/05/29 20:22)推噓3(3推 0噓 10→)留言13則, 1人參與討論串1/1
(代PO)
大家好,小弟最近在學浮點數
有幾個運算觀念卡關,因此來這邊求助大家。
這邊問題都以IEEE 754 單精度浮點數為例
(即1個sign bit,8個 exponent bit,23個mantissabit)
第一個問題:
兩個浮點數在算加減法的時候,exponent小的mantissa要對齊exponent大的mantissa
也就是要看兩個浮點數的exponent差距多少來看mantissa要移位多少
那如果exponent小的那個的mantissa在移位過後超過mantissa所能表示的範圍
要把超過範圍的那幾個bit一起算,還是要捨去呢?
舉例來說
我要算兩個浮點數相減
第一個數:
0 10010011 0000 0000 0000 0000 1111 111
| |------| |--------------------------|
sign exponent mantissa
第二個數:
1 10001110 0000 0000 0000 0111 1111 111
| |------| |--------------------------|
sign exponent mantissa
第一個數的exponent換成十進位是147,第二個數的exponent換成十進位是142
而147-127(bias)=20,142-127=15
所以事實上上面兩個數可以變為:
第一個數:
1.0000 0000 0000 0000 1111 111 * 2^20
第二個數:
-1.0000 0000 0000 0111 1111 111 * 2^15
因為第二個數比第一個數的次方少五,所以要右移5個bit
那麼問題來了,移完之後是會變成
(一)所有bit都保留,因此共要28bit表示mantissa
-0.0000 1000 0000 0000 0011 1111 1111 *(2^20)
|----|
這五個bit超過23bit
(二)超過23bit之後直接砍掉,因此滿足23bit表示mantissa
-0.0000 1000 0000 0000 0011 111 *(2^20)
(三)加入round,guard,sticky三個bit去考慮,因此用25bit表示mantissa
-0.0000 1000 0000 0000 0011 1111 1 且設S=1(因為砍掉後面三個1)
| |
G R
是上面(一)、(二)、(三)的哪一種呢?
因為這三種不同的移位方式會造成最後答案都不一樣,
所以我想IEEE 754應該會有明確的規範。
我個人是比較傾向於第(三)種,
因為如果是第(一)種的話,兩個浮點數若exponent差太多
那就要保存一大堆數字,像是兩數的exponent如果差了一百
那小的exponent很可能就要保存一百個0外加原本的23個mantissa
等於要保存123個bit,以硬體的角度而言應該是不會這樣設計?
第二個問題:
在網路上查到的引入round,guard後的rounding方法大概是這樣
若
(一): (G,R) = (0,0)>捨去
(二): (G,R) = (0,1)>捨去
(三): (G,R) = (1,0)>看sticky bit是多少決定要不要捨or進
(四): (G,R) = (1,1)>進位
我對於(一),(二),(四)這三種方式都能接受
但是(三),若(G,R) = (1,0)的話
換成十進位不就是0.5,以四捨五入的角度來說不是就是直接進位嗎?
為什麼還要看sticky是多少來決定要不要進位呢?
第三個問題:
如圖:
https://imgur.com/a/bqOdrDt
簡單來說就是這兩個浮點數做減法
並且用2補數的方式來做 中間過程我大概都可以接受
而綠框的部分是最後的結果,因為正規化所以Guard以及Round bit都會往左一位
接著藍框的部分是要rounding了
我不懂的是
為什麼此時的(G,R)明明是(1,0) 且S=1
應該是要進位的
但是他藍框的地方卻不考慮G,只考慮R
然後就直接捨去了呢?
目前主要就這三個問題,希望各位可以替我解答一下,感激不盡!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.160.49.195 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/Grad-ProbAsk/M.1590754974.A.FB1.html
※ 編輯: ayn775437403 (118.160.49.195 臺灣), 05/29/2020 21:55:22
→
06/01 03:08,
5年前
, 1F
06/01 03:08, 1F
→
06/01 03:08,
5年前
, 2F
06/01 03:08, 2F
→
06/01 03:08,
5年前
, 3F
06/01 03:08, 3F
→
06/01 03:08,
5年前
, 4F
06/01 03:08, 4F
推
06/01 03:11,
5年前
, 5F
06/01 03:11, 5F
→
06/01 03:11,
5年前
, 6F
06/01 03:11, 6F
推
06/01 03:14,
5年前
, 7F
06/01 03:14, 7F
→
06/01 03:14,
5年前
, 8F
06/01 03:14, 8F
你好,感謝你的回覆
針對我第一個問題我有在c_and_cpp版得到解答了
連結在這:
https://www.ptt.cc/bbs/C_and_CPP/M.1590905575.A.34F.html
所以第一個問題的答案應該是:(一),
也就是運算過程中如果有移位超過mantissa所能表示範圍的bit,
仍要保留,並且拿去運算,最後得到的結果再做rounding
不能在運算的過程中就把這些超過的bit給rounding掉
而我有用這個網站驗證一下:http://weitz.de/ieee/
發現如果是用第(三)種方法,答案不是正確的。
不過我現在對GRS的位子有點疑惑。
請問您認為正確的GRS位子會是在哪裡呢?
我認為要找GRS,應該是要先做完normalize才能找
我的找法是:G是mantissa最後一個bit的右邊第一位,R是G的右邊一個bit,
S是R右邊所有bit做OR運算
(以IEEE 單精度來舉例,mantissa有23bit,
Guard bit就是第24bit,Round bit就是第25bit)
例如:我有一個浮點數加法運算,運算完後得到:
1.1111 0000 1111 0000 1101 1011 0011 1100 * 2^15 (假設已經normalize了)
mantissa多達了32bit,所以要rounding,因此我的G,R會取在:
1.1111 0000 1111 0000 1101 1011 0011 1100 * 2^15
| ||-------|
G R這邊做OR得到S=1
G=mantissa的"第24bit",R=mantissa的"第25bit"
所以GR=10,S=1>要進位
=>因此最後答案為1.1111 0000 1111 0000 1101 110 * 2^15
不知道這樣理解對不對呢?
謝謝
※ 編輯: ayn775437403 (123.195.195.29 臺灣), 06/01/2020 15:28:23
推
06/04 03:58,
5年前
, 9F
06/04 03:58, 9F
→
06/04 03:58,
5年前
, 10F
06/04 03:58, 10F
→
06/04 03:58,
5年前
, 11F
06/04 03:58, 11F

→
06/04 03:59,
5年前
, 12F
06/04 03:59, 12F
→
06/04 03:59,
5年前
, 13F
06/04 03:59, 13F