コレクションによって返されるフィールドがいくつかあります
2.4200
2.0044
2.0000
次のような結果が欲しい
2.42
2.0044
2
String.Format
で試しましたが、2.0000
を返し、N0
に設定すると他の値も丸められます。
入力IS文字列の場合、これほど単純ではありませんか?次のいずれかを使用できます。
string.Format("{0:G29}", decimal.Parse("2.0044"))
decimal.Parse("2.0044").ToString("G29")
2.0m.ToString("G29")
これはすべての入力で機能するはずです。
UpdateStandard Numeric Formats を確認してください。ドキュメントに明記されているように、精度指定子を明示的に29に設定する必要がありました。
ただし、数値がDecimalで精度指定子が省略されている場合は、常に固定小数点表記が使用され、末尾のゼロは保持されます
0.000001などの値に注意してください。 G29形式では、可能な限り最短で表示されるため、指数表記に切り替わります。
string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))
は、結果として「1E-08」を返します。
私は同じ問題に出くわしましたが、文字列への出力を制御できない場合、ライブラリによって処理されました。 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();
私の意見では Custom Numeric Format Strings を使用する方が安全です。
decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
このコードを使用して、「G29」科学表記法を回避します。
public static string DecimalToString(decimal dec)
{
string strdec = dec.ToString(CultureInfo.InvariantCulture);
return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
ハッシュ(#
)シンボルを使用して、必要な場合に末尾の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%
http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/ からエレガントなソリューションを見つけました
基本的に
10進数v = 2.4200M;
v.ToString( "#。######"); // 2.42を返します。 #の数は、サポートする10進数の数です。
非常に低レベルのアプローチですが、高速な整数計算を使用するだけで(これは低速の文字列解析やカルチャに依存するメソッドを使用しない)最もパフォーマンスの高い方法になると思います。
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);
}
これは動作します:
decimal source = 2.4200m;
string output = ((double)source).ToString();
または、初期値がstring
の場合:
string source = "2.4200";
string output = double.Parse(source).ToString();
このコメント に注意してください。
数値が表すものと値の管理方法によって異なります。通貨であるか、丸めまたは切り捨てが必要か、この丸めは表示のみに必要ですか?
表示用にフォーマットを検討する場合、数値は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"];
10進数を保持する場合は、次の例を試してください。
number = Math.Floor(number * 100000000) / 100000000;
非常に簡単な答えは、TrimEnd()を使用することです。結果は次のとおりです。
double value = 1.00;
string output = value.ToString().TrimEnd('0');
出力は1値が1.01の場合、出力は1.01
これは簡単です。
decimal decNumber = Convert.ToDecimal(value);
return decNumber.ToString("0.####");
テスト済み。
乾杯:)