使用浮點數相減的方式,舍入不起作用。即使使用浮點數相減的圓形連接
IEEE754-2008,4.3.1說「roundTiesToEven ......如果包圍不可表示無限精確的結果,兩個最接近的浮點數同樣臨近,一個以偶數至少顯著位須交付」
英特爾文檔說,這是默認模式,更明確地定義它:
https://software.intel.com/en-us/node/503710
我會先通過浮點加法走 - 來驗證我的假設 - 因爲我希望它的工作原理。然後,我會稍微修改我的測試案例,以顯示我的理解失敗的地方。
讓我們兩個單浮點數,這裏代表了「binary32」格式:
S Exponent Significand
0 10000010 00000000000000000000001 (0x41000001)
130
0 01111111 00000000000000000000100 (0x3F800004)
127
添加它們,我轉向具有較小指數(第二個操作數)數的尾數向右3處(我還添加隱含的領先的1這裏):兩個(100)之間
1.00000000000000000000001
+ 0.00100000000000000000000 100
----------------------------
1.00100000000000000000001
由於移出值中旬的方式,它應該輪總和爲偶數值:
1.00100000000000000000010
在二進制中,全部價值是:
0 10000010 00100000000000000000010 (0x41100002)
我可以驗證這一點:
#include <stdint.h>
#include <stdio.h>
union uval {
float fval;
int32_t ival;
};
int main()
{
union uval a, b, c;
a.ival = 0x41000001;
b.ival = 0x3F800004;
c.fval = a.fval + b.fval;
printf("%08x\n", c.ival);
}
打印:
./a.out
41100002
如果我添加一個到第一個操作數:
a.ival = 0x41000002;
我得到同樣的東西。它圓潤下到甚至造成:
./a.out
41100002
到目前爲止,一切都很好。但是,如果我用的是原始值和修改的第二個參數通過符號位設置爲1是負數:
a.ival = 0x41000001;
b.ival = 0xBF800004;
我得到:
./a.out
40E00001
那就是:
0 10000001 11000000000000000000001
129
第二個參數對齊後,結果應該仍然在兩個值之間。在這種情況下,爲什麼沒有達到平衡的價值呢?
爲什麼你期望最終的結果是介於兩者之間的一半,而不是完全可以代表的? –
由於我在對齊時將數字「100」移出第二個操作數(源操作數的指數相差3)。 – JeffB
你有沒有想過在重要意義上發生的事情,結果變化的指數? –