kowala's home

kowala's home
這裡是我的學習筆記,陸續增加中。
http://kowala21.blogspot.com

2013-02-21

C++ 4捨5入問題

如果我們要取到小數2位的話,可以用 decimal 及 Math.Round

但請注意下面的問題[1]

double d1 = 30.745;
Console.WriteLine(Math.Round(d1, 2, MidpointRounding.AwayFromZero));
//結果是3.75

Console.WriteLine(Math.Round(1.43 * 21.5, 2, MidpointRounding.AwayFromZero));
//結果是3.74

double d2 = 1.43 * 21.5;
Console.WriteLine(Math.Round(d2, 2, MidpointRounding.AwayFromZero));
//結果是3.74

decimal d3 = Convert.ToDecimal(1.43 * 21.5);
Console.WriteLine(Math.Round(d3, 2, MidpointRounding.AwayFromZero));
//結果是3.75

但另一種方法可以安全準確的轉換,就是把它取整數,再變回來

取到小數2位 *100

double d1 = 30.745;
double d2 = int(d1*100); //3074 無條件捨去
double d3 = int(d1*100+0.5); //3075 4捨5入

變回來

d2=d2/100; //30.74
d3=d3/100; //30.75 4捨5入

把上面合起來就是

double d1 = 30.745;
double d2 = int(d1*100+0.5)/100; //30.75

如果要取小數三位 *1000

double d1 = 30.745678;
double d2 = int(d1*1000+0.5)/1000; //30.746

如果要取小數四位 *10000

double d1 = 30.745678;
double d2 = int(d1*10000+0.5)/10000; //30.7457

把它寫成函數就是

/******************************************
四捨五入,使用整數法
round(double 來源數值, int 取小數幾位)
*******************************************/
double round(double src,int n){
    double res;
    int i,k=1;
    for(i=0;i<n;i++)k*=10;
    res=int(src*k+0.5);
    res/=k;
    return res;
}

使用範例

double d1 = 30.745678;
double d2 =round(d1,3);//取小數3位
//30.746


參考資料
1. http://social.msdn.microsoft.com/Forums/zh-TW/234/thread/9465c613-98a0-46d9-bbff-f71a50db4eaf/

沒有留言:

張貼留言

請提供您的寶貴意見 ;-)