線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:4437
推到 Plurk!
推到 Facebook!

浮點數型態的差異???

答題得分者是:speedup
todaynow
一般會員


發表:2
回覆:4
積分:1
註冊:2007-04-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-04-24 12:34:11 IP:220.130.xxx.xxx 訂閱
請問各位高手大大~
procedure TForm1.Button1Click(Sender: TObject);
var aa:real;
bb:string;
begin
aa:=3.209;
bb:='asdfsad';
if (aa>=3.2) and (aa<=3.209) then bb:='3.21';
showmessage(bb);
end;

以上的程式執行後會出現bb還是為asdfsad,照理說 if 的判斷式會成立所以bb應該會是3.21

為什麼 aa(3.209)會不小於等於3.209呢?

但如果將aa宣告成real48就正常了,但又會有另一個問題產生就是將aa轉成字串型態時(即floattostr(aa))
結果會變成3.20899999999892

當宣告變數為real或real48時為什麼會出現以上的問題呢??

再麻煩各位大大幫我看看啦!~~~感謝~
------
**************************
努力在delphi的世界中......
speedup
資深會員


發表:19
回覆:259
積分:280
註冊:2003-07-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-04-25 11:02:44 IP:60.248.xxx.xxx 訂閱
因為double /extended/real48/single 是用2進位來儲存 小數的
只要是用2進位來儲存10 進位的小數 就難以避免某些10進位的小數只能以近似值來儲存
稱之為浮點誤差(你可以簡單想像用2進位來兜10進位的小數 是用 1/2 1/4 1/8 1/16 .... 來兜的 當然某些小數無法兜出來)
因次 若你的小數不超過4位可以用Currency 來儲存可避免浮點誤差的問題
若超過四位想避免浮點誤差的話可用TBcd型態 不過TBcd型態在四則運算上都必須用特定的function 來運算處理起來比較麻煩)
或是盡量提高精確度(用extended型態 但是還是會有浮點誤差)

------
唉~
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-04-25 11:23:11 IP:220.130.xxx.xxx 訂閱
大多數的浮動小數點型態,如float, real, double之類的,都是使用IEEE 754的方式來儲存資料,這種方式只能確保在某一位以前的數值是正確的
如果你希望數值是完全正確且可以比較的,應該可以用Currency,這種固定小數位的型態來解決,
Real48我不是很清楚它的實作方式是什麼,不過看了一下help,它確實是提到這一段
Real48is maintained for backward compatibility. Since its storage format is not native to the Intel processor architecture, it results in slower performance than other floating-point types.
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
todaynow
一般會員


發表:2
回覆:4
積分:1
註冊:2007-04-24

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-05-03 13:27:38 IP:220.130.xxx.xxx 訂閱
謝謝以上大大的回答~
------
**************************
努力在delphi的世界中......
系統時間:2024-05-16 22:03:46
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!