2

我需要将十进制数格式化为货币,但我不希望在此过程中进行任何舍入。

例如(示例文化是 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

ToString("C20") -- C 采用精度后缀

编辑:哎呀,显然没有读过这个问题。

.ToString("C20").Trim('0') 似乎是解决方法,但是当您使用 string.Format 时这不起作用...

于 2009-07-24T20:55:27.563 回答
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 回答
0

是的。这是另一个论坛的答案:

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

于 2009-07-24T20:53:26.973 回答
0

您可以尝试编写一个正则表达式来摆脱所有那些尾随的 0。

于 2009-07-24T21:17:16.303 回答