後続ゼロなしで10進数を表示する最良の方法


107

丸めを行わずにc#でこれらの文字列表現として小数を出力する表示フォーマッターはありますか?

// decimal -> string

20 -> 20
20.00 -> 20
20.5 -> 20.5
20.5000 -> 20.5
20.125 -> 20.125
20.12500 -> 20.125
0.000 -> 0

{0.#}は丸められ、一部のトリムタイプ関数を使用しても、グリッド内のバインドされた数値列では機能しません。

回答:


147

表示する必要がある小数点以下の最大数はありますか?(あなたの例は最大5です)。

もしそうなら、私は "0。#####"でフォーマットするとあなたが望むことをするだろうと思います。

    static void Main(string[] args)
    {
        var dList = new decimal[] { 20, 20.00m, 20.5m, 20.5000m, 20.125m, 20.12500m, 0.000m };

        foreach (var d in dList)
            Console.WriteLine(d.ToString("0.#####"));
    }

4
そして、あなたはいつもフォーマットで#記号の法外な*数を投げることができます。*科学的ではありません
Anthony Pegram 2010年

3
+1-ちなみに、先頭の#は必要ありません。「0。#####」も同様に機能します。そしてどちらにしても、これはゼロから丸められます(ちょうどFYI)。
TrueWill、

14
@TrueWill実際には違いがあります。d == 0.1mの場合、「0.#」は「0.1」をレンダリングし、「#。#」は「.1」を先頭の0なしでレンダリングします。どちらが間違っていても正しいとは限りません。どちらが必要かによって異なります。
AaronLS

4
常に小数点以下1桁を表示する必要があるため、フォーマット文字列を使用しました"0.0#"
Hammerを使用したコード

1
下記のアーウィンメイヤーの回答を参照してください。
shlgug

32

G書式指定子を適切に使用する方法を学びました。MSDNドキュメントを参照してください。精度が指定されていない場合、10進数タイプの後続ゼロは保持されることを示す少し下のメモがあります。なぜ彼らがこれを行うのかはわかりませんが、精度に最大桁数を指定することで問題が解決するはずです。したがって、小数をフォーマットするにG29は、最善の方法です。

decimal test = 20.5000m;
test.ToString("G"); // outputs 20.5000 like the documentation says it should
test.ToString("G29"); // outputs 20.5 which is exactly what we want

21
これにより、0.00001が1E-05として表示されます
sehe

17

この文字列形式は、「0。#############################」のようになります。ただし、小数の有効桁数は最大で29桁であることに注意してください。

例:

? (1000000.00000000000050000000000m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.00000000000050000000001m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.0000000000005000000001m).ToString("0.#############################")
-> 1000000.0000000000005000000001

? (9223372036854775807.0000000001m).ToString("0.#############################")
-> 9223372036854775807

? (9223372036854775807.000000001m).ToString("0.#############################")
-> 9223372036854775807.000000001

4
これが問題に対する最も一般的な答えです。これが10進数のデフォルトの「G」形式でない理由がわかりません。末尾のゼロは情報を追加しません。Microsoftのドキュメントには、10進数に関する奇妙な警告があります: docs.microsoft.com/en-us/dotnet/standard/base-types/… ただし、数値が10進数で精度指定子が省略されている場合は、固定小数点表記が常に使用されます末尾のゼロは保持されます。
エリックローラー

10

これは、上で見たもののもう1つのバリエーションです。私の場合、小数点の右側のすべての有効数字を保持する必要があります。つまり、最上位の数字の後にすべてゼロをドロップします。共有したほうがいいと思いました。私はこれの効率を保証することはできませんが、美学を達成しようとするとき、あなたはすでに非効率にかなりのろわれています。

public static string ToTrimmedString(this decimal target)
{
    string strValue = target.ToString(); //Get the stock string

    //If there is a decimal point present
    if (strValue.Contains("."))
    {
        //Remove all trailing zeros
        strValue = strValue.TrimEnd('0');

        //If all we are left with is a decimal point
        if (strValue.EndsWith(".")) //then remove it
            strValue = strValue.TrimEnd('.');
    }

    return strValue;
}

それだけです、私の2セントを投入したかっただけです。


3
これは簡単に最適なソリューションであり、「0.0」でも爆発しません。整数をオプションで「1.0」として表示するデフォルトフラグを追加しました。これにより、すべての小数が一列に表示されます。これが最良の答えではない理由が理解できません。
Steve Hibbert 2014

2
これは、誰かがすでにあなたに文字列を渡した場合に特に便利です。これをToTrimmedString(this string strValue)に変更して、最初の行を削除するだけです。
PRMan

それは良い点です。私がこれを書いているとき、私はすでに小数または何かであった値を扱っていたと思うので、すべてを網羅したいと思いました。代わりに、そのメソッドの本体を、代わりに文字列を受け入れる別のオーバーロードされたメソッド内に置くことができます。
dyslexicanaboko

ToTrimmedString()を呼び出すことができる場合は良い解決策ですが、フォーマット文字列に制限される場合が多くあります。
マイクマリナウスキ

1
小数点記号は文化に固有である必要がありますが、これは良い解決策だと思います。小さな質問ですstrValue.TrimEnd('0').TrimEnd('.')が、EndsWith小切手ではなくなぜですか?
nawfal

5

dyslexicanabokoの答えに基づくが、現在の文化に依存しない別の解決策:

public static string ToTrimmedString(this decimal num)
{
    string str = num.ToString();
    string decimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    if (str.Contains(decimalSeparator))
    {
        str = str.TrimEnd('0');
        if(str.EndsWith(decimalSeparator))
        {
            str = str.RemoveFromEnd(1);
        }
    }
    return str;
}

public static string RemoveFromEnd(this string str, int characterCount)
{
    return str.Remove(str.Length - characterCount, characterCount);
}

すごい。SqlDecimalを除き、地域の設定に関係なく、CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparatorです。
user2091150

4

拡張方法:

public static class Extensions
{
    public static string TrimDouble(this string temp)
    {
        var value = temp.IndexOf('.') == -1 ? temp : temp.TrimEnd('.', '0');
        return value == string.Empty ? "0" : value;
    }
}

コード例:

double[] dvalues = {20, 20.00, 20.5, 20.5000, 20.125, 20.125000, 0.000};
foreach (var value in dvalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.ToString().TrimDouble()));

Console.WriteLine("==================");

string[] svalues = {"20", "20.00", "20.5", "20.5000", "20.125", "20.125000", "0.000"};
foreach (var value in svalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.TrimDouble()));

出力:

20 --> 20
20 --> 20
20,5 --> 20,5
20,5 --> 20,5
20,125 --> 20,125
20,125 --> 20,125
0 --> 0
==================
20 --> 20
20.00 --> 2
20.5 --> 20.5
20.5000 --> 20.5
20.125 --> 20.125
20.125000 --> 20.125
0.000 --> 0

1
「20.00-> 2」良い行動ではないと思います。これを修正するには、TrimEndを2回呼び出します。TrimEnd( '0'); TrimEnd( '、');
Vadim 2014年

2
上記のコードは使用しないでください。@VadymKはその動作に欠陥があることは正しいです。ピリオドがない場合、ピリオドの前にある末尾のゼロを削除します。
Sevin7 2016年

2
stackoverflowの回答はコピーと貼り付けではありません。それらは学習の源として使用されます。このサンプルコードはIndexOf、文字列内の文字を検索するために使用する方法を示しています。小数なしで問題を解決するために例を調整するのは非常に簡単です。
jgauffin 2016年

2

私はそれがすぐに可能であるとは思わないが、このような単純な方法はそれを行うべきです

public static string TrimDecimal(decimal value)
{
    string result = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
    if (result.IndexOf('.') == -1)
        return result;

    return result.TrimEnd('0', '.');
}

2

箱から出すのはとても簡単です:

Decimal YourValue; //just as example   
String YourString = YourValue.ToString().TrimEnd('0','.');

これにより、小数点からすべての後続ゼロが削除されます。

上記の例のよう.ToString().TrimEnd('0','.');に、10進変数に追加して、後続ゼロなしでa Decimalをa に変換する必要がありますString

一部の地域では、それは.ToString().TrimEnd('0',',');(ポイントの代わりにコンマを使用しますが、確実にパラメーターとしてドットとコンマを追加することもできます)でなければなりません。

(両方をパラメーターとして追加することもできます)


気付かないかもしれませんが、params引数を扱う場合、明示的に配列を作成する必要はありません。したがって、詳細の代わりに、TrimEnd("0".ToCharArray())次のように書くことができますTrimEnd('0')(注:のchar代わりに単一を渡すchar[])。
Dan Tao

@ダンタオ:ありがとう、私はそれを忘れていました。C#を使って久しぶりです。どちらのバージョンでも機能しますが、投稿を編集しました。
メルビン、

@Mervin:a charではなくを渡す必要があります(つまりstring、二重引用符ではなく単一引用符です)。私はあなたのためにそれを修正しました-うまくいけばあなたは気にしないでしょう。
Dan Tao

1
ソリューションは「2」のような出力を生成します。ゼロになったとき。
jgauffin

2
次に、.ToString()。TrimEnd( '0')。TrimEnd( '。')を呼び出すことをお勧めします。また、「。」の代わりに CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparatorを使用して、さまざまな文化で機能するようにすることをお勧めします。
ΕГИІИО


0

私は次のコードで終わりました:

    public static string DropTrailingZeros(string test)
    {
        if (test.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.TrimEnd('0');
        }

        if (test.EndsWith(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.Substring(0,
                test.Length - CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator.Length);
        }

        return test;
    }

0

私はこの亜種に終わりました:

public static string Decimal2StringCompact(decimal value, int maxDigits)
    {
        if (maxDigits < 0) maxDigits = 0;
        else if (maxDigits > 28) maxDigits = 28;
        return Math.Round(value, maxDigits, MidpointRounding.ToEven).ToString("0.############################", CultureInfo.InvariantCulture);
    }

利点:

実行時に表示するポイントの後の最大有効桁数を指定できます。

丸め方法を明示的に指定できます。

文化を明示的に制御できます。


0

拡張メソッドを作成できます

public static class ExtensionMethod {
  public static decimal simplify_decimal(this decimal value) => decimal.Parse($"{this:0.############}");
}

0

私は自分のプロジェクトの1つに合うように自分で以下の拡張メソッドを作成しましたが、おそらく他の人に役立つでしょう。

using System.Numerics;
using System.Text.RegularExpressions;
internal static class ExtensionMethod
{
    internal static string TrimDecimal(this BigInteger obj) => obj.ToString().TrimDecimal();
    internal static string TrimDecimal(this decimal obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this double obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this float obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this string obj)
    {
        if (string.IsNullOrWhiteSpace(obj) || !Regex.IsMatch(obj, @"^(\d+([.]\d*)?|[.]\d*)$")) return string.Empty;
        Regex regex = new Regex("^[0]*(?<pre>([0-9]+)?)(?<post>([.][0-9]*)?)$");
        MatchEvaluator matchEvaluator = m => string.Concat(m.Groups["pre"].Length > 0 ? m.Groups["pre"].Value : "0", m.Groups["post"].Value.TrimEnd(new[] { '.', '0' }));
        return regex.Replace(obj, matchEvaluator);
    }
}

ただし、への参照が必要になりますSystem.Numerics

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.