2

10 進数を通貨としてフォーマットする必要がありますが、その過程で丸めを行いたくありません。

例 (例のカルチャは en-US)

Dim money = 1234.556789D
money.ToString("C") ' Yields $1,234.56 (notice the rounding & truncating)

money.ToString("C99") ' Yields $1,234.556789000000000000....0 -- close but not perfect, those trailing zeros are unwanted.

' I want something that would result in this...
money.ToString("??") ' Yields $1,234.56789

' likewise....
money = 0.1D
money.ToString("??") ' Yields $0.10  (notice that it at least matches the culture's currency format -- two decimal places)

このアプリケーションのすべてのユーザーが en_US ルールを使用すると仮定すると、"??" を作成できます。「$#,##0.00######################################」のようにハードコーディングされたものであること########################### 」 - しかし、それは私の胃を混乱させます. 私が求めていることを達成するための組み込みの方法はありますか?

4

5 に答える 5

2

あなたはこのようなことをすることができます...

var money = 1234.556789D;
Console.WriteLine(money.ToString(GetFormat(money)));

money = .1D;

Console.WriteLine(money.ToString(GetFormat(money)));

次のメソッドを使用してフォーマット文字列を取得します...

static string GetFormat(double input)
{
    // get the number of decimal places to show
    int length = input.ToString().Length - input.ToString().IndexOf(".") - 1;

    // return the currency format string to use with decimal.ToString()
    return string.Format("C{0}", length < 2 ? 2 : length);
}

さらに一歩進めたい場合は、これらすべてを拡張メソッドにラップして、ToString() 内から GetFormat() メソッドを呼び出す必要がないようにすることもできます。これにより、見た目が少しすっきりするかもしれません。

于 2009-07-24T21:15:56.743 に答える
1

これを行う組み込みの方法がないように見えることを見て、私は次のような独自の拡張メソッドを展開することになりました...

Public Function ToUnroundedCurrency(ByVal value As Decimal) As String
    Dim valueAsString As String = value.ToString() ' Some loss of precision happens here, but it is not a concern.

    Dim decimalLocation As Integer = valueAsString.IndexOf(".")

    ' Get number of digits after the decimal place in the number
    Dim numberOfDecimalPlaces As Integer = 0
    If (decimalLocation > 0) Then numberOfDecimalPlaces = valueAsString.Length - decimalLocation - 1

    ' The currency formatter has a limit of 99 decimal places -- due to the decimal -> ToString() conversion above, this will never happen, but being defensive anyway.
    If (numberOfDecimalPlaces > 99) Then
        numberOfDecimalPlaces = 99
    ElseIf (numberOfDecimalPlaces < CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits) Then
        ' also make sure we at least have the minimum required decimal places
        numberOfDecimalPlaces = CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits
    End If

    Return value.ToString("C" & numberOfDecimalPlaces)
End Function

ごくわずかな精度の損失に気付きました。私たち (またはおそらく誰でも) は、制限に遭遇するのに十分な小数の値を扱っていないでしょう。

于 2009-07-24T22:26:58.360 に答える
1

ToString("C20") -- C は精度サフィックスを取ります

編集:おっと、明らかに質問を読んでいませんでした。

.ToString("C20").Trim('0') は修正のようですが、string.Format を使用している場合は機能しません...

于 2009-07-24T20:55:27.563 に答える
0

末尾の 0 をすべて取り除く正規表​​現を作成してみてください。

于 2009-07-24T21:17:16.303 に答える
0

はい。別のフォーラムからの回答は次のとおりです。

http://forums.asp.net/p/1266337/2380486.aspx

于 2009-07-24T20:53:26.973 に答える