全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4808
推到 Plurk!
推到 Facebook!

四捨五入遇到的怪問題

答題得分者是:jimmy_wei
redjeff
一般會員


發表:12
回覆:16
積分:10
註冊:2006-07-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-12-24 13:54:07 IP:60.244.xxx.xxx 未訂閱
procedure TForm1.Button1Click(Sender: TObject);
var a,b,c : Double;
begin
a:=102531;
b:=0.075;
c:=a*b;
Showmessage(Format('%.2f',[a*b]));
Showmessage(Format('%.2f',[102531*0.075]));
end;

數值一樣,一個有用變數接收,一個沒有,答案算出來竟然不一樣,現在已改成用運算的方式(X*100 0.5)/100
jimmy_wei
高階會員


發表:9
回覆:176
積分:147
註冊:2003-08-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-12-25 13:19:01 IP:123.194.xxx.xxx 訂閱
你的問題怪怪的~~
我試了也覺得怪怪的~~
如果是要四捨五入,給你一個含式
iType傳2進去,就是四捨五入了
iDec請傳要到小數後幾位
fValue是數字

//Type=1(4in5cut),2(all in)
function XRound(fValue: Real; iDec,iType: Integer): Real;
var
i, iCheckValue: Integer;
Str: String;
bAddOne: Boolean;
rResultValue: Real;
begin
bAddOne:= False;
for i:=0 to iDec do
fValue:= fValue * 10;
Str:= FloatToStr(fValue);
if Pos('.',Str) > 0 then
Str:= Copy(Str,1,Pos('.',Str)-1);
iCheckValue:= StrToInt(Str);
if iType = 1 then
begin
if iCheckValue mod 10 >= 5 then
bAddOne:= True
end else if iType = 2 then
bAddOne:= True;
if Length(Copy(Str,1,Length(Str)-1)) = 0 then
iCheckValue:= 0
else
iCheckValue:= StrToInt(Copy(Str,1,Length(Str)-1));
if bAddOne then
iCheckValue:= iCheckValue 1;
rResultValue:= iCheckValue;
for i:=1 to iDec do
rResultValue:= rResultValue / 10;
Result:= rResultValue;
end;
frappe
中階會員


發表:88
回覆:114
積分:95
註冊:2008-10-21

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-12-30 04:43:35 IP:115.82.xxx.xxx 訂閱
Delphi有一個Bug或是特色= =
就是
四捨六入五成雙
五成雙是指前一位雙數進位,單數捨棄,夠怪吧= =
如果要4捨5入就自己寫程式吧
redjeff
一般會員


發表:12
回覆:16
積分:10
註冊:2006-07-06

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-12-30 09:00:52 IP:59.125.xxx.xxx 未訂閱
四捨六入五成雙,這個我曉得,但是我遇到的卻是同樣的數值,一個有用變數接,一個沒有,而答案就不一樣
看來真的要自己寫了,拿樓上的大大FUNCTION來看看了~~~

===================引 用 frappe 文 章===================
Delphi有一個Bug或是特色= =
就是
四捨六入五成雙
五成雙是指前一位雙數進位,單數捨棄,夠怪吧= =
如果要4捨5入就自己寫程式吧
RootKit
資深會員


發表:16
回覆:358
積分:419
註冊:2008-01-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-12-30 15:16:16 IP:61.222.xxx.xxx 訂閱
var a,b,c : Extended;
begin
a:=102531;
b:=0.075;
c:=a*b;
Showmessage(Format('%.2f',[a*b]));
Showmessage(Format('%.2f',[102531*0.075]));
end;

自己不了請不要牽拖 Delphi。
Delphi 是無辜地。

PS.四捨六入五成雙 是指 Round 函數。
redjeff
一般會員


發表:12
回覆:16
積分:10
註冊:2006-07-06

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-12-31 12:57:48 IP:60.244.xxx.xxx 未訂閱
這個方法試過了是ok,謝謝大大囉,但是稍微改了一下,又不行了
最主要的原因是因為我的數值是從資料庫裡帶出來的,資料型態是float,所以我改成下列的方式,結果還是有問題
var a,b,c : Extended;
d,e : Double;
begin
d:=102531;
e:=0.0750;
a:=d;
b:=e;
c:=a*b;
Showmessage(Format('%.2f',[c]));
Showmessage(Format('%.2f',[102531*0.075]));
===================引 用 RootKit 文 章===================
var a,b,c : Extended;
begin
a:=102531;
b:=0.075;
c:=a*b;
Showmessage(Format('%.2f',[a*b]));
Showmessage(Format('%.2f',[102531*0.075]));
end;

自己不了請不要牽拖 Delphi。
Delphi 是無辜地。

PS.四捨六入五成雙 是指 Round 函數。
RootKit
資深會員


發表:16
回覆:358
積分:419
註冊:2008-01-02

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-12-31 15:29:55 IP:61.222.xxx.xxx 訂閱
Double 型態( IEEE 754)。會有精密度精確的問題。
7689.825
實際上內容是 7689.82499999.. 使用 %.2f 只會取小數點第三位值做出判斷四捨五入就會變成 7689.82
就如同 TDateTime = Double
我們不能用if A = B 來判斷時間,必須用範圍值 來判斷。

因此如果你的資料庫為運算的結果。在型態不可改下,就只能透過自訂函數解決。
redjeff
一般會員


發表:12
回覆:16
積分:10
註冊:2006-07-06

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-01-03 09:05:36 IP:59.121.xxx.xxx 未訂閱
原來如此,謝謝詳細的回答^_^
可惜不可以給二個人分數,所以我把分數給jimmy wei,因為我用他的function來處理目前的問題~~~~
但也謝謝rookit的回答,在觀念上更加的清楚~~~~~
===================引 用 RootKit 文 章===================
Double 型態( IEEE 754)。會有精密度精確的問題。
7689.825
實際上內容是 7689.82499999.. 使用 %.2f 只會取小數點第三位值做出判斷四捨五入就會變成 7689.82
就如同 TDateTime = Double
我們不能用if A = B 來判斷時間,必須用範圍值 來判斷。

因此如果你的資料庫為運算的結果。在型態不可改下,就只能透過自訂函數解決。
系統時間:2024-04-27 1:01:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!