4

私は System.Decimal 番号を持っています

0.00123456789

有効数字3桁に丸めたいです。私が期待する

0.00123

動作が切り捨てではなく丸め動作になります。.Net でこれを行う防弾方法はありますか?

4

4 に答える 4

5

あなたはこれを試すことができます...しかし、私は何も保証しません... 20分で書かれてテストされ、 https: //stackoverflow.com/a/1581007/613130からのPyrolisticalのコードに基づいてい ますは変数にalongを使用します( a の精度は 15 ~ 16 桁であるのに対し、a の精度は 18 ~ 19 であるため、aで十分です)。shifteddoublelonglongdecimaldecimal

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は無料です。

于 2013-08-09T11:52:01.317 に答える
0

例:

decimal a = 1.9999M;
decimal b = Math.Round(a, 2); //returns 2
于 2013-08-09T10:27:51.937 に答える
-1

これを試して ... decimalVar.ToString ("#.##");

于 2013-08-09T10:01:40.860 に答える