GCC中關於浮點運算的問題

2021-08-30 10:42:20 字數 2992 閱讀 7775

最近讀書《深入理解計算機系統》裡第二章中的「intel ia32 浮點運算」,發現其中給出的測試程式有些問題:

浮點數暫存器使用的是80位的擴充套件精度格式

float 型別使用的是32位精度格式

double 型別使用的是64位精度格式

書中給出的例子是

#includedouble recip(int denom)

void do_nothing(){}

void test1(int denom)

main()

我的系統是ubuntu9.04

gcc 版本 4.3.3 (ubuntu 4.3.3-5ubuntu4)
第一步:不帶優化的編譯

coffee@coffee-laptop:~$ gcc -o test test.c

coffee@coffee-laptop:~$ ./test

test1 t1: r1 0.100000 == r2 0.100000

test1 t2: r1 0.100000 == r2 0.100000

第二步:帶有o2優化的編譯

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

test1 t2: r1 0.100000 == r2 0.100000

加入書中給出的函式2

void test2(int denom)
第一步:不帶優化的編譯

coffee@coffee-laptop:~$ gcc -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

第二步:帶有o2優化的編譯

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

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

查了些資料,國內對這部分的解釋還是太少了,通過優編譯--反彙編,比較得出的三種不同的反編譯的匯程式設計序,得出結論。原來在不帶優化的編譯中,浮點計算的結果先是儲存在浮點暫存器,採用的是80位的擴充套件精度格式,即r1;而r2計算的結果已經被轉換到64位的double型別,所以比較的結果不同。

參考的反彙編

不帶有優化的編譯,下面的是函式test2的反彙編**

da:	55                   	push   %ebp

db: 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 顯然是不相等的。對於常用金額資料比較...