最近讀書《深入理解計算機系統》裡第二章中的「intel ia32 浮點運算」,發現其中給出的測試程式有些問題:
浮點數暫存器使用的是80位的擴充套件精度格式
float 型別使用的是32位精度格式
double 型別使用的是64位精度格式
書中給出的例子是
#includedouble recip(int denom)我的系統是ubuntu9.04void do_nothing(){}
void test1(int denom)
main()
gcc 版本 4.3.3 (ubuntu 4.3.3-5ubuntu4)第一步:不帶優化的編譯
coffee@coffee-laptop:~$ gcc -o test test.c第二步:帶有o2優化的編譯coffee@coffee-laptop:~$ ./test
test1 t1: r1 0.100000 == r2 0.100000
test1 t2: r1 0.100000 == r2 0.100000
coffee@coffee-laptop:~$ gcc -o2 -o test test.c執行結果並不是意料中的coffee@coffee-laptop:~$ ./test
test1 t1: r1 0.100000 == r2 0.100000
test1 t2: r1 0.100000 == r2 0.100000
test1 t1: r1 0.100000 != r2 0.100000加入書中給出的函式2test1 t2: r1 0.100000 == r2 0.100000
void test2(int denom)第一步:不帶優化的編譯
coffee@coffee-laptop:~$ gcc -o test test.c第二步:帶有o2優化的編譯coffee@coffee-laptop:~$ ./test
test1 t1: r1 0.100000 == r2 0.100000
test1 t2: r1 0.100000 == r2 0.100000
test2 t1: r1 0.100000 != 1.0/10.0
coffee@coffee-laptop:~$ gcc -o2 -o test test.c這裡主要有兩方面的問題coffee@coffee-laptop:~$ ./test
test1 t1: r1 0.100000 == r2 0.100000
test1 t2: r1 0.100000 == r2 0.100000
test2 t1: r1 0.100000 == 1.0/10.0
1.是浮點暫存器的使用問題,儲存在浮點暫存器中的浮點數並不等於記憶體中的浮點數
2.gcc對浮點數的支援,特別是在使用了o2優化編譯的時候
明天繼續研究,今天到此,先休息!
繼續 2010-01-30(ps:昨天和同學逛街去了,哇哈哈!)
首先,對源程式的編譯採用命令列選項 -ffloat-store,該命令將每乙個浮點計算的結果在使用之前都必須儲存到儲存器中,
測試結果
coffee@coffee-laptop:~$ gcc -ffloat-store -o test3 test.c查了些資料,國內對這部分的解釋還是太少了,通過優編譯--反彙編,比較得出的三種不同的反編譯的匯程式設計序,得出結論。原來在不帶優化的編譯中,浮點計算的結果先是儲存在浮點暫存器,採用的是80位的擴充套件精度格式,即r1;而r2計算的結果已經被轉換到64位的double型別,所以比較的結果不同。coffee@coffee-laptop:~$ ./test3
test1 t1: r1 0.100000 == r2 0.100000
test1 t2: r1 0.100000 == r2 0.100000
test2 t1: r1 0.100000 == 1.0/10.0
參考的反彙編
不帶有優化的編譯,下面的是函式test2的反彙編**
da: 55 push %ebpdb: 89 e5 mov %esp,%ebp
dd: 83 ec 28 sub $0x28,%esp
e0: 8b 45 08 mov 0x8(%ebp),%eax
e3: 89 04 24 mov %eax,(%esp)
e6: e8 fc ff ff ff call e7 eb: dd 5d f0 fstpl -0x10(%ebp)
ee: db 45 08 fildl 0x8(%ebp)
f1: d9 e8 fld1
f3: de f1 fdivp %st,%st(1)
f5: dd 45 f0 fldl -0x10(%ebp)
f8: da e9 fucompp
fa: df e0 fnstsw %ax
fc: 9e sahf
fd: 0f 94 c0 sete %al
100: 0f 9b c2 setnp %dl
103: 21 d0 and %edx,%eax
105: 0f b6 c0 movzbl %al,%eax
108: 89 45 fc mov %eax,-0x4(%ebp)
JS中的浮點運算問題
最近又遇到在前台進行浮點運算的問題,一開始從網上直接複製了一段浮點運算的 在測試中發現依然存在問題。現在將修改過的 貼出啦,與大家分享。var floatcalculate catch e try catch e m math.pow 10,math.max r1,r2 return arg1 m ...
PHP 關於浮點數運算的問題
x 0.5 echo x 0.1 echo echo x 0.1 echo echo x 0.1 echo echo x 0.1 echo echo x 0.1 echo 今天在做一些相關的浮點型資料運算時,出現 2.7755575615629e 17 的問題。當然具體例項不是這樣的!google ...
關於浮點型的運算 比較
1.常見問題 a 0.1 b 0.7 var dump a b 0.8 列印出來的值居然為 boolean false printf 20f a printf 20f b 0.10000000000000000555 0.69999999999999995559 顯然是不相等的。對於常用金額資料比較...