Even more, if you perform Math.Round(0.5, 0) you may expect, that the result is 1. But no, since the default midpoint rounding is to even, you will get 0, while Math.Round(1.5, 0) still results in 2. A little bit strange, eh? Well, I'm not mathematican and I please you to bear with me, because I cannot explain that 'midpoint rounding to even versus midpoint rounding away from zero'-thingy.
But anyway, for business applications you would rather expect:
- Round(input 0.5, precisionDigits 0) is 1
- Round(input 1.5, precisionDigits 0) is 2
/// <summary>
/// Rounds a decimal value in commercial way
/// </summary>
/// <param name="input">
/// The figure subject to round
/// </param>
/// <param name="roundingSize">
/// The rounding size
/// </param>
/// <returns>
/// The round result
/// </returns>
public static decimal CommercialRound(decimal input, decimal roundingSize)
{
    decimal ret = input;
    if (roundingSize != 0)
    {
        ret = Math.Round(input / roundingSize,
MidpointRounding.AwayFromZero) 
            * roundingSize;
    }
    return ret;
}
/// <summary>
/// Rounds down to given rounding size
/// </summary>
/// <param name="input">
/// The figure subject to round
/// </param>
/// <param name="roundingSize">
/// The size to round to
/// </param>
/// <returns>
/// The rounded value
/// </returns>
public static decimal RoundDown(decimal input, decimal roundingSize)
{
    decimal ret = input;
    if (roundingSize != 0)
    {
        ret = Math.Floor(input / roundingSize)
* roundingSize;
    }
    return ret;
}
/// <summary>
/// Rounds up to given rounding size
/// </summary>
/// <param name="input">
/// The figure subject to round
/// </param>
/// <param name="roundingSize">
/// The size to round to
/// </param>
/// <returns>
/// The rounded value
/// </returns>
public static decimal RoundUp(decimal input, decimal roundingSize)
{
    decimal ret = input;
    if (roundingSize != 0)
    {
        ret = Math.Ceiling(input /
roundingSize) * roundingSize;
    }
    return ret;
}
As you can see, they work with the decimal type, but I'm quite sure you can create overloaded method with any other floating data type you work with.
Furthermore you can convert these methods easely to extension methods, just add the this keyword before the type keyword of the first parameter in the method signature, like:
public static decimal CommercialRound(this decimal input, decimal roundingSize)
That way you can write code like:
var decimalValue = 15.54887m;
var roundedDecimalValue = decimalValue.CommercialRound(0.25);
Happy rounding :)
 
No comments:
Post a Comment