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.
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.
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).
double inputValue = 48.00; inputValue = Math. Round(inputValue, 2); will result 48 only.
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
double d = 1.2345;
Math.Round(d, 2);
the code above should do the trick.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With