Ejemplo n.º 1
0
 public void Currency_can_round(CurrencyRoundingMethod method, decimal value, decimal result)
 {
     value.Round(method).ShouldEqual(result);
 }
        /// <summary>
        /// Rounds a currency value
        /// </summary>
        /// <param name="value">Value to round</param>
        /// <param name="method">Currency rounding method</param>
        /// <returns>Rounded value</returns>
        /// <see cref="https://en.wikipedia.org/wiki/Cash_rounding"/>
        public static decimal Round(this decimal value, CurrencyRoundingMethod method)
        {
            var result = Math.Round(value, 2);
            var frac   = (result - Math.Truncate(result)) * 10;

            if (frac == decimal.Zero)
            {
                return(result);
            }

            switch (method)
            {
            case CurrencyRoundingMethod.Down005:
            case CurrencyRoundingMethod.Up005:
                frac = (frac - Math.Truncate(frac)) * 10;

                if (method == CurrencyRoundingMethod.Down005)
                {
                    frac = frac < 5 ? -1 * frac : 5 - frac;
                }
                else
                {
                    frac = (frac < 5 ? 5 : 10) - frac;
                }

                result += frac / 100;
                break;

            case CurrencyRoundingMethod.Down01:
            case CurrencyRoundingMethod.Up01:
                frac = (frac - Math.Truncate(frac)) * 10;

                if (method == CurrencyRoundingMethod.Down01 && frac == 5)
                {
                    frac = -5;
                }
                else
                {
                    frac = frac < 5 ? -1 * frac : 10 - frac;
                }

                result += frac / 100;
                break;

            case CurrencyRoundingMethod.Interval05:
                frac *= 10;

                if (frac < 25)
                {
                    frac *= -1;
                }
                else
                {
                    frac = (frac < 50 || frac < 75 ? 50 : 100) - frac;
                }

                result += frac / 100;
                break;

            case CurrencyRoundingMethod.Interval1:
            case CurrencyRoundingMethod.Up1:
                frac *= 10;

                if (method == CurrencyRoundingMethod.Up1 && frac > 0)
                {
                    result = Math.Truncate(result) + 1;
                }
                else
                {
                    result = frac < 50 ? Math.Truncate(result) : Math.Truncate(result) + 1;
                }
                break;
            }

            return(result);
        }