Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rounding double values in C#

I want a rounding method on double values in C#. It needs to be able to round a double value to any rounding precision value. My code on hand looks like:

public static double RoundI(double number, double roundingInterval) {

    if (roundingInterval == 0.0)
    {
        return;
    }

    double intv = Math.Abs(roundingInterval);
    double sign = Math.Sign(number);
    double val = Math.Abs(number);

    double valIntvRatio = val / intv;
    double k = Math.Floor(valIntvRatio);
    double m = valIntvRatio - k;

    bool mGreaterThanMidPoint = ((m - 0.5) >= 1e-14) ? true : false;
    bool mInMidpoint = (Math.Abs(m - 0.5) < 1e-14) ? true : false;
    return (mGreaterThanMidPoint || mInMidpoint) ? sign * ((k + 1) * intv) : sign * (k * intv);
}

So RoundI(100, 3) should give 99 and RoundI(1.2345, 0.001) should give 1.235.

The problem is, RoundI(1.275, 0.01) returns 1.27, rather than 1.28. This is because when executing double valIntvRatio = val/intv, that is, double valIntvRatio = 1.275 / 0.01, it gives 0.12749999999999. I know this is a problem with double representation in any programming language. My question is, is there a standard code to do things like this, without the need to worry about precision on double? Here I set the tolerant to 1e-14, but this is too restrict for this problem and I don't know what is the correct tolerance to be set. Thank you for any help.

like image 898
Steve Avatar asked Jan 25 '10 02:01

Steve


People also ask

Is there a rounding function in C?

The round( ) function in the C programming language provides the integer value that is nearest to the float, the double or long double type argument passed to it. If the decimal number is between “1 and. 5′′, it gives an integer number less than the argument.

How do you round up in C?

In the C Programming Language, the ceil function returns the smallest integer that is greater than or equal to x (ie: rounds up the nearest integer).

How do you round a double to two decimal places in C#?

double inputValue = 48.00; inputValue = Math. Round(inputValue, 2); will result 48 only.


3 Answers

Example of using decimal, as Kibbee pointed out

double d = 1.275; Math.Round(d, 2);          // 1.27 Math.Round((decimal)d, 2); // 1.28  
like image 73
2 revs, 2 users 73% Avatar answered Oct 02 '22 10:10

2 revs, 2 users 73%


double d = 1.2345;

Math.Round(d, 2);

the code above should do the trick.

like image 42
AceMark Avatar answered Oct 02 '22 09:10

AceMark


If you actually need to use double just replace it below and it will work but with the usual precision problems of binary floating-point arithmetics.

There's most certainly a better way to implement the "rounding" (almost a kind of bankers' rounding) than my string juggling below.

public static decimal RoundI(decimal number, decimal roundingInterval)
{
   if (roundingInterval == 0) { return 0;}

   decimal intv = Math.Abs(roundingInterval);
   decimal modulo = number % intv;
   if ((intv - modulo) == modulo) {
       var temp = (number - modulo).ToString("#.##################");
       if (temp.Length != 0 && temp[temp.Length - 1] % 2 == 0) modulo *= -1;
   }
    else if ((intv - modulo) < modulo)
        modulo = (intv - modulo);
    else
        modulo *= -1;

    return number + modulo;
}
like image 21
Jonas Elfström Avatar answered Oct 02 '22 11:10

Jonas Elfström