10

In C# I want a function that rounds a given double to a given amount of decimals. I always want my function to return a value (which can be a string) with the given amount of decimals. If necessary, trailing zeros need to be added.

Example:

string result = MyRoundingFunction(1.01234567, 3);
// this must return "1.012"

That's easy, it's just rounding and converting to string. But here comes the problem:

string result2 = MyRoundingFuntion(1.01, 3);
// this must return "1.010"

Is there a convenient/standard way to do this, or do I manually need to add trailing zeros?

Any help is appreciated. Note that in the real life application I can't hard code the number of decimals.

Bart Gijssens
  • 1,572
  • 5
  • 20
  • 38

5 Answers5

15

You can create a formatter like this example:

int numDigitsAfterPoint = 5;
double num = 1.25d;
string result = num.ToString("0." + new string('0', numDigitsAfterPoint));

or (more easily)

string result = num.ToString("F" + numDigitsAfterPoint);

As a sidenote, ToString uses the MidpointRounding.AwayFromZero instead of the MidpointRounding.ToEven (also called Banker's Rounding). As an example:

var x1 = 1.25.ToString("F1");
var x2 = 1.35.ToString("F1");
var x3 = Math.Round(1.25, 1).ToString();
var x4 = Math.Round(1.35, 1).ToString();

These will produce different result (because Math.Round normally uses MidpointRounding.ToEven)

And note that internally ToString() seems to do some "magic" before rounding digits. For doubles, if you ask him less than 15 digits, I think it rounds to 15 digits first and then rounds to the right number of digits. See here https://ideone.com/ZBEis9

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • 1
    Perfect! I did not know you could do 1.25.ToString("F1"). Thanks. – Bart Gijssens Oct 20 '11 at 09:28
  • @BaGi If I have to tell the truth, I wanted to change it to the `num` variable, but I forgot to do it. It works clearly :-) (in the same way you can do `"HelloWorld".Substring(5)`) – xanatos Oct 20 '11 at 09:34
6

You should first round, then format.

String.Format("{0:0.000}", Math.Round(someValue, 2));

What you should read is:

Math.Round

String.Format, Custom Numeric Format

As option you could use the extension to support that

Extension Methods

  • 1
    I don't want to hard code the number of decimals. In my application the number of decimals depends on what is inside a unit system database and user preferences. – Bart Gijssens Oct 20 '11 at 08:54
  • That was just an example, you should be able to solve the problem by yourself from this point. The ultimate solution will not give you the wisdom and you will often lock on simple problems. – Damian Leszczyński - Vash Oct 20 '11 at 08:58
  • 1
    I appreciate your attempt to educate me. I was falsely under the impression that I did not make myself clear enough in the part where I said that I did not want to hard code the number of decimals. However, your example and links did not lead me to what I believe is the essence of the best solution here, and that is what xanatos posted as an answer: to use things like "F2" as formatter. – Bart Gijssens Oct 20 '11 at 09:27
4
string.format("{0:f2}", value);
Steven
  • 166,672
  • 24
  • 332
  • 435
  • Yes but I don't want to hard code the number of decimals. In my application the number of decimals depends on what is inside a unit system database and user preferences. – Bart Gijssens Oct 20 '11 at 08:53
  • 1
    It isn't `d`. It is `f`. `d` is for integers. From [MSDN](http://msdn.microsoft.com/it-it/library/dwhawy9k.aspx) `Result: Integer digits with optional negative sign. Supported by: Integral types only.` – xanatos Oct 20 '11 at 08:55
2

Your solution (does what you want).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            string result = MyRoundingFunction(1.01234567, 3);
            Console.WriteLine(result);
            result = MyRoundingFunction(1.01, 3);
            Console.WriteLine(result);
            Console.ReadLine();
        }

        public static string MyRoundingFunction(double value, int decimalPlaces)
        {
            string formatter = "{0:f" + decimalPlaces + "}";
            return string.Format(formatter, value);
        }
    }
}
Valdemar
  • 950
  • 1
  • 12
  • 20
1

Simply:

decimal.Round(mydouble, 2).ToString("0.00")
Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206