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

RoundTo 與 SimpleRoundTo 的正確性與穩定性

尚未結案
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-11-12 12:21:58 IP:210.64.xxx.xxx 訂閱
真的是一個老問題了,不過因為之前幾乎沒需要去精準處理這部份,所以僅管看了一些人的發表,但自己卻沒去深入。

首先,我要把我的環境講一下: bcb 6 經 update4 (build 10.166) xp系統下

測式:

[code cpp]

SetRoundMode(rmTruncate); //這行很重要
double d = SimpleRoundTo(1.245, -2);
double d2 = RoundTo(1.245, -2);
double d3 = SimpleRoundTo(1.015, -2);
double d4 = RoundTo(1.015, -2);

ShowMessage(FloatToStr(d));
ShowMessage(FloatToStr(d2));
ShowMessage(FloatToStr(d3));
ShowMessage(FloatToStr(d4));
[/code]

SimpleRound在rmTruncate模式下,似乎比較穩定的呈現想要的四捨五入!

RoundTo的部份則有點小問題,沒有照四捨六入五成雙的規則(banker's) 。你看d4的值就知道,沒如預期的變1.02(成偶數)

當然,SetRoundMode 下的各種模式的配合,幾乎好像沒有一個模式能把二種round的規則都正確呈現。大家有時間可以幫忙測一下…
此外,我還不是很確定我說「SimpleRound在rmTruncate模式下」一定「正確」。
大家有什麼看法? 是否也可以驗一下上面的正確性? 或者,反過來說,是否確定「無論如何都不準」的結論?

謝謝!

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2009-11-12 12:26:46, 註解 無‧
maplefog
一般會員


發表:16
回覆:24
積分:13
註冊:2008-11-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-11-13 21:42:20 IP:140.118.xxx.xxx 訂閱

之前有研究了一下這個,拿出來獻醜一下

round : 四捨六入五成雙
trunc(x 0.5) : 四捨五入

[code cpp]
//---------------------------------------------------------------------------
#pragma hdrstop
#include
#include
#include
double round(double x);
double trunc(double x);
//---------------------------------------------------------------------------
using namespace std;
#pragma argsused

int main(int argc, char* argv[])
{
double in = 1.5;
cout << round(in) << "\n";
cout << trunc(in 0.5) << "\n";
cout << trunc(in) << "\n";
cout << ceil(in) << "\n";
cout << floor(in) << "\n";
system("Pause");
return 0;
}
//---------------------------------------------------------------------------
double trunc(double x)
{
if(x>0)
return floor(x);
else
return ceil(x);
}
//---------------------------------------------------------------------------
double round(double x)
{
if(ceil(x 0.5)==floor(x 0.5))
{
int a = (int)ceil(x);
if (a%2 == 0)
return ceil(x);
else
return floor(x);
}
else
return
floor(x 0.5);
}
//---------------------------------------------------------------------------

[/code]

測試值 -1.5 -1 -0.6 -0.5 -0.4 0 0.4 0.5 0.6 1 1.5
round(x) -2 -1 -1 0 0 0 0 0 1 1 2
trunc(x 0.5) -1 0 0 0 0 0 0 1 1 1 2

編輯記錄
maplefog 重新編輯於 2009-11-13 21:43:21, 註解 無‧
maplefog 重新編輯於 2009-11-13 21:43:44, 註解 無‧
maplefog 重新編輯於 2009-11-13 21:44:06, 註解 無‧
maplefog 重新編輯於 2009-11-13 21:44:32, 註解 無‧
brook
資深會員


發表:57
回覆:323
積分:371
註冊:2002-07-12

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-11-14 12:28:33 IP:60.251.xxx.xxx 訂閱
1.我覺得無論是float或是double的字典裡,沒有1.015這個值,而他能用的值可能會比1.015多一點點或少一點點,而實際上是比1.015這個值少一點點.即然是少一點點,你覺得四捨五入1.015會是多少,就像1.0149999999999999999999999999四捨五入會是多少?
2.真的要精確,只能用int系列.
3.而我比較喜歡另一種方式,但要事先聲明,也是不準,參考看看.
整數四捨五入我會加0.5多一點點,如0.5001再捨棄小數.
你的例子我會多加0.005001,再捨棄多餘部份.
系統時間:2024-11-22 11:52:56
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!