-2

文字列オブジェクトを取得して、10 進数から 4 dp に変換する必要があります。

たとえば、次のようになります。

string val = "145.83011";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);

145.8301 を戻す - 良い

でも:

string val = "145.8300";
decimal sss = Math.Round(Convert.ToDecimal(val), 4);

145.83 を戻す 145.8300 にする必要がある

10 進形式で必要なので、文字列形式オプションを使用できません。

ありがとうロブ

4

2 に答える 2

2

1 つのオプションは、文字列操作を 3 回使用することです。

  • 元のテキストを値に解析しdecimalます (これにより、元の小数点以下の桁数が保持されます)
  • 文字列フォーマットを使用して、小数点以下 4 桁までの文字列を完成させます。(最大で4DPMath.Roundが存在することを保証しますが、正確に4DP ではないことを保証します。)
  • フォーマットの結果を解析して、decimal正確に 4DP の値に戻します。

だから、このようなもの:

public static decimal Force4DecimalPlaces(string input)
{
    decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture); 
    string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
    return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
}

このような文字列変換を使用することには抵抗がありますが、代替手段は比較的トリッキーです。生のビットを取得し、さまざまな部分を分割して仮数とスケールを見つけてから、適切に調整するか、一連の算術演算を実行して適切なスケールにすることができます。(1.0000m を掛ける Jeppe のアプローチは完全に正しいかもしれません -それが正しいと文書化されているかどうかはわかりません.

上記のコードは、私が知る限り、半分で切り上げを実行することに注意してください。たとえば、1.12345 は 1.1235 に変換されます。

コメントに出力を含むサンプル:

using System;
using System.Globalization;

class Test
{
    static void Main()        
    {
        Console.WriteLine(Force4DecimalPlaces("0.0000001")); // 0.0000
        Console.WriteLine(Force4DecimalPlaces("1.000000"));  // 1.0000
        Console.WriteLine(Force4DecimalPlaces("1.5"));       // 1.5000
        Console.WriteLine(Force4DecimalPlaces("1.56789"));   // 1.5679
    }

    public static decimal Force4DecimalPlaces(string input)
    {
        decimal parsed = decimal.Parse(input, CultureInfo.InvariantCulture); 
        string intermediate = parsed.ToString("0.0000", CultureInfo.InvariantCulture);
        return decimal.Parse(intermediate, CultureInfo.InvariantCulture);
    }
} 
于 2013-09-13T13:22:53.847 に答える
0

Convert.ToDecimaldecimal.Parse 両方とも、文字列の末尾のゼロを保持します (aSystem.Decimalは合計で最大 28 ~ 29 桁なので、ほとんどの場合、すべての末尾のゼロを格納する余地があります)。

またMath.Round(..., 4)、小数点以下第 4 位までの後続ゼロを保持します。

したがって、質問の前提が間違っています。あなたの例は、あなたが望むものを取り戻します。

いずれにせよ、同様に引数として受け取るオーバーロードを指定することを検討してください。その場合、変換はローカル カルチャーに依存しません。IFormatProviderCultureInfo.InvariantCulture

代わりに、文字列のように文字列を処理し、文字列に含まれていない末尾のゼロを追加する場合は、次を使用し"145.83"ます

string val = "145.83";
decimal sss = Math.Round(
    decimal.Parse(val, CultureInfo.InvariantCulture) * 1.0000m,
    4);

エピローグ: のような数値による乗算と除算が気に入らない場合は1.0000m、 を使用decimal.GetBitsして内部表現を取得します。適切な 10 の累乗で乗算または除算して整数の「部分」を調整し、対応する数値を減算または加算してスケールの「部分」を調整します。スケールは、96 ビット整数から始めて、小数点を左に移動する桁数をカウントします。

于 2013-09-13T13:21:30.613 に答える