從事ASP.NET in C#開發快一年了,今天才知道,C#中保留小數位數時沒有使用截斷的方式。
項目中要用到以截斷的方式取小數點后兩位,故寫了以下方法:
/// <summary>
/// 將小數值按指定的小數位數截斷
/// </summary>
/// <param name="d">要截斷的小數</param>
/// <param name="s">小數位數,s大於等於0,小於等於28</param>
/// <returns></returns>
public static decimal ToFixed(decimal d, int s)
{
decimal sp = Convert.ToDecimal(Math.Pow(10, s));
if (d < 0)
return Math.Truncate(d) + Math.Ceiling((d - Math.Truncate(d)) * sp) / sp;
else
return Math.Truncate(d) + Math.Floor((d - Math.Truncate(d)) * sp) / sp;
}
順帶提一下:
-
double和decimal的ToString("#.##")方法使用的是四舍五入;
-
靜態類System.Math下的Round(decimal d, int decimals)方法,舍入的方式使用的是“四舍六入五成雙”;
-
靜態類System.Math下的Round(decimal d, int decimals, MidpointRounding mode)的第三個參數是枚舉參數,指示如何處理中間值(5);
靜態類System.Math的方法:http://msdn.microsoft.com/zh-cn/library/system.math_methods(v=vs.80)
鳴謝:
這里要謝謝“尒寶..”反饋的Bug,詳情參見1樓和3樓。
在最初的版本中,double與decimal的實現方式是一致的。
“請記住,浮點數只能近似於十進制數字,浮點數的精度決定了浮點數近似於十進制數字的精確程度。”摘自:http://msdn.microsoft.com/zh-cn/library/system.double.aspx
表達式((9.6-9)==0.6)的計算結果是false,因為(9.6-9)的計算結果是:0.59999999999999964;
還有表達式((109.6-100)==(9.6-9))的計算結果是false,有沒有覺得很神奇。。。
因為double的這種特質,double的類似上面decimal的實現,結果可能就是錯誤的(有興趣的同學可以試一下,把上面方法中的數據類型改為double,調用ToFixed(9.6, 1)結果為9.5),經過嘗試,無法使用類似decimal的方式實現double的截斷保留指定的小數位數。。。最后,我作出了一個非常艱難的決定,決定從博文刪除double部分的實現!
decimal是用來表示十進制數的結構(體),它是精確的。。。
如果double的值介於decimal.MinValue和decimal.MaxValue之間,可以轉換為decimal,然后調用上面的方法。。。好別扭啊啊啊!~!~!~