如何将.Net中的System.Decimal舍入到一些重要数字中

我有一个System.Decimal数字

0.00123456789

我希望得到3位重要数字。 我预计

0.00123

行为是舍入行为而不是截断。 在.Net中是否有防弹方法可以做到这一点?

你可以尝试这个…但我不保证任何事情……在20分钟内编写并测试并根据来自https://stackoverflow.com/a/1581007/613130的 Pyrolistical代码有一个很大的不同之处在于他对shifted变量使用long (因为double的精度为15-16位,而long有18-19,所以long就足够了),而我使用decimal (因为decimal的精度为28-29)位)。

 public static decimal RoundToSignificantFigures(decimal num, int n) { if (num == 0) { return 0; } // We are only looking for the next power of 10... // The double conversion could impact in some corner cases, // but I'm not able to construct them... int d = (int)Math.Ceiling(Math.Log10((double)Math.Abs(num))); int power = n - d; // Same here, Math.Pow(10, *) is an integer number decimal magnitude = (decimal)Math.Pow(10, power); // I'm using the MidpointRounding.AwayFromZero . I'm not sure // having a MidpointRounding.ToEven would be useful (is Banker's // rounding used for significant figures?) decimal shifted = Math.Round(num * magnitude, 0, MidpointRounding.AwayFromZero); decimal ret = shifted / magnitude; return ret; } 

如果你不信任(int)Math.Ceiling(Math.Log10((double)你可以使用它:

 private static readonly decimal[] Pows = Enumerable.Range(-28, 57) .Select(p => (decimal)Math.Pow(10, p)) .ToArray(); public static int Log10Ceiling(decimal num) { int log10 = Array.BinarySearch(Pows, num); return (log10 >= 0 ? log10 : ~log10) - 28; } 

我已经在另外20分钟内写了它(是的,我已经测试了所有数值-28 – +28)的所有Math.Pow((double), p) )。 它似乎工作,并且它比基于double s的C#公式慢20%。 它基于静态的pows数组和BinarySearch 。 幸运的是BinarySearch已经“建议”下一个元素,当它找不到一个:-)时,所以Ceiling是免费的。

SqlDecimal具有快速计算和调整精度的方法。

 public static decimal RoundToSignificantFigures(decimal num, int n) { SqlDecimal value = New SqlDecimal(num); if (value.Precision > num){ int digits = num - (value.Precision - value.Scale); value = SqlDecimal.Round(value, digits); value = SqlDecimal.AdjustScale(value, (digits>0 ? digits : 0) - dstValue.Scale, True); } return value.Value; } 

试试这个…… decimalVar.ToString ("#.##");

在示例中:

 decimal a = 1.9999M; decimal b = Math.Round(a, 2); //returns 2