私は System.Decimal 番号を持っています
0.00123456789
有効数字3桁に丸めたいです。私が期待する
0.00123
動作が切り捨てではなく丸め動作になります。.Net でこれを行う防弾方法はありますか?
あなたはこれを試すことができます...しかし、私は何も保証しません... 20分で書かれてテストされ、 https: //stackoverflow.com/a/1581007/613130からのPyrolisticalのコードに基づいてい
ますは変数にalong
を使用します( a の精度は 15 ~ 16 桁であるのに対し、a の精度は 18 ~ 19 であるため、aで十分です)。shifted
double
long
long
decimal
decimal
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 分でそれを書きました (そして、はい、Math.Pow((double), p)
すべての値 -28 から +28 についてすべてをテストしました)。動作しているようで、s に基づく C# 式よりも 20% 遅いだけdouble
です)。pows と a の静的配列に基づいていますBinarySearch
。幸いなことにBinarySearch
、次の要素が見つからない場合、 はすでに次の要素を「提案」しています :-) ため、Ceiling
は無料です。
例:
decimal a = 1.9999M;
decimal b = Math.Round(a, 2); //returns 2
これを試して ... decimalVar.ToString ("#.##");