4

I have encountered something very weird when it comes to the standard numeric format strings in C#. This is probably a known quirk but i can't find anything documenting it and i can't figure out a way to actually get what i want.

I want to take a number like 17.929333333333489 and format it with no decimal places. So i just want "17". But when run this code.

decimal what = 17.929333333333489m;
Console.WriteLine(what.ToString("F0"));

I get this output

18

Looking at Microsoft's documentation on it their examples show the same output.

https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

//          F:                     -195489100.84
//          F0:                    -195489101
//          F1:                    -195489100.8
//          F2:                    -195489100.84
//          F3:                    -195489100.838

Here is a code example showing the odd issue.

http://csharppad.com/gist/d67ddf5d0535c4fe8e39

This issue is not only limited to the standard ones like "F" and "N" but also the custom ones like "#".

How can i use the standard "F0" formatter and not have it round my number?

Chris Rice
  • 728
  • 2
  • 9
  • 32

2 Answers2

6

From the documentation on Standard Numeric Format Strings:

xx is an optional integer called the precision specifier. The precision specifier ranges from 0 to 99 and affects the number of digits in the result. Note that the precision specifier controls the number of digits in the string representation of a number. It does not round the number itself. To perform a rounding operation, use the Math.Ceiling, Math.Floor, or Math.Round method.

When precision specifier controls the number of fractional digits in the result string, the result strings reflect numbers that are rounded away from zero (that is, using MidpointRounding.AwayFromZero).

So the documentation does indeed discuss this, and there is no apparent way to prevent rounding of the output purely through a format string.

The best I can offer is to truncate the number yourself using Math.Truncate():

decimal what = 17.929333333333489m;
decimal truncatedWhat = Math.Truncate(what);
Console.WriteLine(truncatedWhat.ToString("F0"));
Community
  • 1
  • 1
devuxer
  • 41,681
  • 47
  • 180
  • 292
1

I believe using decimal with "m" at the end rounds up at the given decimal place.

Here is what I experimented.

decimal what = 17.429333333333489m;
Console.WriteLine(what.ToString("F0"));
Console.WriteLine(what.ToString("N0"));
Console.WriteLine(what.ToString("F1"));
Console.WriteLine(what.ToString("N1"))
17
17
17.4
17.4

If you want to get 17, I used different approach using int and deciam

double what = 17.929333333333489;
Console.WriteLine(string.Format("{0:0}", (int)what));
Console.WriteLine(string.Format("{0:0}", what));
Console.WriteLine(string.Format("{0:0.00}", Math.Floor(what*100)/100));
Console.WriteLine(string.Format("{0:0.00}", what));
17
18
17.92
17.93
Sean83
  • 493
  • 4
  • 14