Search code examples
c#stringformat

C# format string: How to show or zero decimal places, or two decimal places?


When formatting a price for the tabular presentation, I prefer to see only the integer part of the number if there is no significant decimal part. However, when there is also the decimal part, I would like to see always two decimal places -- including the possible trailing zero. Is it possible to write a format string that causes that behavior?

Examples:

value        wanted
  0.000           0 
123.000         123
123.456      123.46
123.400      123.40     <-- How to do that case?

So far, I have the format string # ###0.##, and it displays the last case as:

123.400       123.4     <-- How to add the trailing zero?

Update: I agree it may look overcomplicated. To clarify the reasons for the needs, the table is to be displayed at the web page, and vast majority of the values is naturally integer (like number of pieces). Knowing that, the tabular representation is much more readable without the decimal zeros, and the columns can be more narrow. Occasionally, I need to display values that are naturally float. In the case, I want to show two decimal places. When the whole table is split to pages, most of he pages can be displayed in the integer form. Sometimes, the column contains the float, the page is not that nice to display; anyway, no information is distorted (say, rounded to integer). Also, the float comes in groups (because of the nature of the data). Then pages with decimals look better when decimal numbers are always displayed using two decimal places.


Solution

  • Well, it may looks ugly, but we can check if we have 0 fractional part within ToString and provide the required format string:

    double item = ...
    
    string text = item.ToString(item % 1 == 0 ? "f0" : "f2");
    

    Demo:

    double[] tests = {
      0,
      123,
      123.456,
      123.4,
      123.003 // it has fractional part
    };
    
    var result = string.Join(Environment.NewLine,
      tests.Select(item => item.ToString(item % 1 == 0 ? "f0" : "f2")));
    
    Console.Write(result);
    

    Output:

    0
    123
    123.46
    123.40
    123.00 // it was 123.003 for which we show fractional part
    

    Edit: If we want 123 instead of 123.00 in the last test case we should compare with 0.005 not with 0:

    item.ToString(item % 1 <= 0.005 ? "f0" : "f2")