web-dev-qa-db-ja.com

末尾のゼロを削除する

コレクションによって返されるフィールドがいくつかあります

2.4200
2.0044
2.0000

次のような結果が欲しい

2.42
2.0044
2

String.Formatで試しましたが、2.0000を返し、N0に設定すると他の値も丸められます。

155
Zo Has

入力IS文字列の場合、これほど単純ではありませんか?次のいずれかを使用できます。

string.Format("{0:G29}", decimal.Parse("2.0044"))

decimal.Parse("2.0044").ToString("G29")

2.0m.ToString("G29")

これはすべての入力で機能するはずです。

UpdateStandard Numeric Formats を確認してください。ドキュメントに明記されているように、精度指定子を明示的に29に設定する必要がありました。

ただし、数値がDecimalで精度指定子が省略されている場合は、常に固定小数点表記が使用され、末尾のゼロは保持されます

UpdateKonrad指摘 コメント:

0.000001などの値に注意してください。 G29形式では、可能な限り最短で表示されるため、指数表記に切り替わります。 string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))は、結果として「1E-08」を返します。

151
Dog Ears

私は同じ問題に出くわしましたが、文字列への出力を制御できない場合、ライブラリによって処理されました。 Decimal型の実装の詳細を調べた後( http://msdn.Microsoft.com/en-us/library/system.decimal.getbits.aspx を参照)、私はきちんとしたトリック(ここでは拡張メソッドとして):

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

小数の指数部は、必要なものだけに削減されます。出力10進数でToString()を呼び出すと、末尾の0なしで数値が書き込まれます。

1.200m.Normalize().ToString();
180
Thomas Materna

私の意見では Custom Numeric Format Strings を使用する方が安全です。

decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
80
Michał Powaga

このコードを使用して、「G29」科学表記法を回避します。

public static string DecimalToString(decimal dec)
{
    string strdec = dec.ToString(CultureInfo.InvariantCulture);
    return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
28
x7BiT

ハッシュ(#)シンボルを使用して、必要な場合に末尾の0のみを表示します。以下のテストを参照してください。

decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;

num1.ToString("0.##");       //13.15%
num2.ToString("0.##");       //49.1%
num3.ToString("0.##");       //30%
13
Fizzix

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/ からエレガントなソリューションを見つけました

基本的に

10進数v = 2.4200M;

v.ToString( "#。######"); // 2.42を返します。 #の数は、サポートする1​​0進数の数です。

9
DHornpout

非常に低レベルのアプローチですが、高速な整数計算を使用するだけで(これは低速の文字列解析やカルチャに依存するメソッドを使用しない)最もパフォーマンスの高い方法になると思います。

public static decimal Normalize(this decimal d)
{
    int[] bits = decimal.GetBits(d);

    int sign = bits[3] & (1 << 31);
    int exp = (bits[3] >> 16) & 0x1f;

    uint a = (uint)bits[2]; // Top bits
    uint b = (uint)bits[1]; // Middle bits
    uint c = (uint)bits[0]; // Bottom bits

    while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
    {
        uint r;
        a = DivideBy10((uint)0, a, out r);
        b = DivideBy10(r, b, out r);
        c = DivideBy10(r, c, out r);
        exp--;
    }

    bits[0] = (int)c;
    bits[1] = (int)b;
    bits[2] = (int)a;
    bits[3] = (exp << 16) | sign;
    return new decimal(bits);
}

private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
    ulong total = highBits;
    total <<= 32;
    total = total | (ulong)lowBits;

    remainder = (uint)(total % 10L);
    return (uint)(total / 10L);
}
2
Bigjim

これは動作します:

decimal source = 2.4200m;
string output = ((double)source).ToString();

または、初期値がstringの場合:

string source = "2.4200";
string output = double.Parse(source).ToString();

このコメント に注意してください。

2
Shimmy

数値が表すものと値の管理方法によって異なります。通貨であるか、丸めまたは切り捨てが必要か、この丸めは表示のみに必要ですか?

表示用にフォーマットを検討する場合、数値はx.ToString( "")

http://msdn.Microsoft.com/en-us/library/dwhawy9k.aspx および

http://msdn.Microsoft.com/en-us/library/0c899ak8.aspx

単に丸める場合は、MidPointRoundingオーバーロードが必要なMath.Roundオーバーロードを使用します

http://msdn.Microsoft.com/en-us/library/ms131274.aspx

データベースから値を取得する場合、変換ではなくキャストを検討してください。double value =(decimal)myRecord ["columnName"];

1
florin

10進数を保持する場合は、次の例を試してください。

number = Math.Floor(number * 100000000) / 100000000;
0
phuongnd

非常に簡単な答えは、TrimEnd()を使用することです。結果は次のとおりです。

double value = 1.00;
string output = value.ToString().TrimEnd('0');

出力は1値が1.01の場合、出力は1.01

0
Raj De Inno

これは簡単です。

decimal decNumber = Convert.ToDecimal(value);
        return decNumber.ToString("0.####");

テスト済み。

乾杯:)

0
Rakesh