[爆卦]浮點數計算機是什麼?優點缺點精華區懶人包

為什麼這篇浮點數計算機鄉民發文收入到精華區:因為在浮點數計算機這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者ayn775437403 (@@@@@@@@@@@@@@@@@@@)看板C_and_CPP標題[...


大家好

小弟目前在修系上計算機方面的課程

老師希望我們寫出一個浮點數的運算單元,

然後以IEEE 754 單精度浮點數為標準,rounding方式是round to nearest even

而老師給的測資都是標準二進位浮點數的格式了,不用自己再轉為IEEE 754浮點數

即輸入會像是這樣:

0 10010011 0000 0000 0000 0000 1111 111
| |------| |--------------------------|
sign exponent mantissa


而我在寫之前想要先確定一下自己觀念對不對

不然到時候觀念不對怕浪費太多時間改程式

所以想要問一個運算的問題:

(以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,以硬體的角度而言應該是不會這樣設計?

還請各位替我解答一下

老師上課浮點數就只是帶過 然後就要我們一周寫出來

實在是有點頭痛Orz

感謝各位!

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.160.137.74 (臺灣)
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1590905575.A.34F.html
firejox: 都告訴你round to nearest even了,就是用那種方式做。 05/31 14:23
firejox: 你提的3個都不是老師要求的 05/31 14:23

那可以請問一下如果要符合要求,小exponent的那個mantissa到底該怎麼移嗎?

因為要對齊大exponent的話,一定會有幾個bit超過mantissa能保存的範圍(23bit)

我有去翻Computer Organization and Design: The Hardware/Software Interface

這本書,但是他舉的例子好像比較接近我提的第(三)種QQ
firejox: 你得到G,R,S後,要根據他們的值額外做進位,最後依然是2 05/31 14:28
firejox: 3bits 05/31 14:28

那請問我的G,R,S有取錯嗎?

(G=第24bit,R=第25bit,S=第25bit後所有bit做OR,所以G=1,R=1,S=1)

那您的意思是:

加入round,guard,sticky三個bit去考慮,

-0.0000 1000 0000 0000 0011 1111 1 且設S=1(因為砍掉後面三個1)
| |
G R

而因為G,R = 1

=>進位

=> -0.0000 1000 0000 0000 0011 111
+) 1
----------------------------------------------------
-0.0000 1000 0000 0000 0100 000

=>第二個數在移完之後變成:-0.0000 1000 0000 0000 0100 000 * 2^20

=>和第一個數運算

是這樣子嗎?

在麻煩您解答一下了,感激不盡
firejox: 不是,rounding 是算完在做的。以位移來說,次方數差超 05/31 15:01
firejox: 過25位是不會影響rounding的結果。 05/31 15:01

f大不好意思,

如果照您說的"rounding是運算完再做"的話,

那我所說的第二個浮點數:

-1.0000 0000 0000 0111 1111 111 * 2^15

要右移五次方的話,超過mantissa 23bit的那五個bit

到底該怎麼處理,去和第一個浮點數:

1.0000 0000 0000 0000 1111 111 * 2^20

運算完後才有正確的結果呢?

我現在用: http://weitz.de/ieee/ 這個網站去算我這兩個數字

答案會是 1.1111 0000 0000 0001 0111 110 * 2^19

但是我怎麼算都算不出這個結果

不好意思問題很多 但是我真的被這問題困擾很久了QQ
firejox: 比方說,你減完得到G是1、R是1,你這結果還要進位才是ro 05/31 15:13
firejox: und to nearest even 的值 05/31 15:14

我能理解您所說的"做完運算(減完後)"還要再rounding,

但是我的問題比較像是,

在中間過程中,如果有一個數字在移位後,

他的mantissa超過了原本格式所能表示的範圍,

那這些超過的bit要如何處理它們,

才會使我可以正確的運算並且得到正確的結果

然後最後再做rounding呢?

因為如果這幾個bit不正確處理的話,最後運算結果再rounding應該也不會對

所以我目前是卡在中間過程中不知道該如何處理這些超過mantissa的bits QQ
firejox: 超過的部分在進位前做保留,以硬體來說多幾位元存不是很 05/31 15:23
firejox: 大的問題。 05/31 15:23
firejox: 像是32位元的無號整數乘法,他會乘完得出64位元的值再取 05/31 15:29
firejox: 32位元 05/31 15:29
firejox: 我上面的部分有地方講錯,round to nearest even需要看4 05/31 15:41
firejox: 個地方,第23位、G、R、S,rounding完會讓第23位爲0。 05/31 15:41
firejox: 更正,第23位不一定爲0 05/31 15:43
firejox: 進位規則是G and (R or S or 第23位),1的話進位,0的 05/31 15:48
firejox: 話捨去 05/31 15:48

您說的"超過的部分在進位前做保留",意思是不管超過幾位,

運算的時候就是把這些超過的存起來照算嗎?

如果是這樣的話我再算一次的過程是:

第一個數:

0 10010011 0000 0000 0000 0000 1111 111
| |------| |--------------------------|
sign exponent mantissa

第二個數:

1 10001110 0000 0000 0000 0111 1111 111
| |------| |--------------------------|
sign exponent mantissa

化成指數形式:

第一個數:

1.0000 0000 0000 0000 1111 111 * 2^20

第二個數:

-1.0000 0000 0000 0111 1111 111 * 2^15

第二個數右移5BIT

=>-0.0000 1000 0000 0000 0011 1111 1111 *(2^20)
|----|
這五個bit超過23bit,但是保留

然後第一個數的1.mantissa減第二個數的1.mantissa:

1.0000 0000 0000 0000 1111 1110 0000

- 0.0000 1000 0000 0000 0011 1111 1111
---------------------------------------------
0.1111 1000 0000 0000 1011 1110 0001

因此目前算出的答案是:0.1111 1000 0000 0000 1011 1110 0001 * 2^20

接著normalized:1.111 1000 0000 0000 1011 1110 0001 * 2^19

但是1.111 1000 0000 0000 1011 1110 0001 * 2^19
||
GR

而有4bit超過23bit,因此要rounding,而G=0,R=0>捨去

其中我G取第24bit,R取第25bit,S=1

因此最後答案為:1.111 1000 0000 0000 1011 1110 * 2^19

這樣子我的運算觀念是對的嗎?

答案和 http://weitz.de/ieee/ 算出來的一樣

但是我怕我會不會是觀念錯誤只是剛好矇對(像是GR取錯之類的)

再請f大幫我看一下了,謝謝您
※ 編輯: ayn775437403 (1.160.137.74 臺灣), 05/31/2020 16:13:13
firejox: 是這樣算沒錯 05/31 16:12

太好了!真的非常感謝您不厭其煩的替我解答這麼久!

希望如果有問題的話還可以再請教您一下!謝謝!
※ 編輯: ayn775437403 (1.160.137.74 臺灣), 05/31/2020 16:14:38
alan23273850: 運算規則規格書找不到嗎?自己都說 IEEE754 了何不 05/31 17:41
alan23273850: 看看原文 05/31 17:41

有,我有去翻IEEE Standard for Floating-Point Arithmetic這個規格書

但是似乎都是在講"運算過後的結果如何rounding"

好像沒有提到如果"運算過程中移位後超過mantissa範圍的bit該如何處理"

當然可能是我沒看很仔細 QQ
※ 編輯: ayn775437403 (123.195.195.29 臺灣), 05/31/2020 22:54:52
suhorng: 在運算的時候就當一般的數學計算做 做完後再 rounding 06/01 00:34
suhorng: 轉回 IEEE754 表示法. 換句話說, 中間步驟做計算時就當 06/01 00:34
suhorng: 成是普通的數學計算, 不要考慮精度跟表示法的限制 06/01 00:35

了解,謝謝您的回復

所以不管中間運算過程中的浮點數超過了mantissa所能表示範圍的多少bit

仍然要把它一起加入運算就對了

然後最後算完的結果如果有多出mantissa所能表示的範圍再rounding掉

應該是這樣理解沒錯吧@@?

謝謝
※ 編輯: ayn775437403 (123.195.195.29 臺灣), 06/01/2020 15:43:18
remember: github上面 testfloat 跟 softfloat 研究一下 06/06 15:57
remember: Point-Arithmetic/dp/0898714826 06/06 15:59
remember: google 一下 這本 不到110頁 好懂又實在 06/06 16:00

你可能也想看看

搜尋相關網站