Format currency without rounding

后端 未结 5 475
萌比男神i
萌比男神i 2021-01-15 04:19

I have the need to format a decimal number as currency but I do not wish for any rounding to occur in the process.

For example (example culture is en-US)

<         


        
相关标签:
5条回答
  • 2021-01-15 04:53

    Yes. Here's the answer from another forum:

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

    0 讨论(0)
  • 2021-01-15 04:59

    You could do something like this...

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

    using the following method to get the format string...

    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);
    }
    

    If you wanted to take it a step further, you could also wrap all of this into an extension method so that you didn't have to call the GetFormat() method from inside ToString() - that might make things look a bit cleaner.

    0 讨论(0)
  • 2021-01-15 05:00

    Seeing that there doesn't seem to be a built-in way of doing this, I ended up rolling my own extension method that looks like...

    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
    

    I noted some negligible loss of precision. We (or anybody probably) wouldn't be dealing with decimal values fractional enough enough to ever run into the limitations.

    0 讨论(0)
  • 2021-01-15 05:07

    ToString("C20") -- C takes a precision suffix

    EDIT: oops, didn't read the question apparently.

    .ToString("C20").Trim('0') seems like the fix, but this doesn't work when you're using string.Format...

    0 讨论(0)
  • 2021-01-15 05:15

    You could try writing a regular expression to get rid of all of those trailing 0's.

    0 讨论(0)
提交回复
热议问题