Ejemplo n.º 1
0
        /// <summary>
        /// Calculates the number of periods remaining on a loan.
        /// </summary>
        /// <param name="rate">The periodic interest rate (applied every period). This must be greater than or equal to zero.</param>
        /// <param name="payment">The payment made each period. This must be greater than or equal to zero and not contain fractional pennies.</param>
        /// <param name="currentBalance">The current balance of the loan. This must be greater than or equal to zero and not contain fractional pennies.</param>
        /// <param name="futureBalance">The future balance of the loan. This must be greater than or equal to zero and not contain fractional pennies.</param>
        /// <param name="payAtBeginningOfPeriod">Set to <c>true</c> to indicate payments are made at the beginning of the period; by default, payments are made at the end of the period.</param>
        /// <returns>The number of periods remaining on the loan.</returns>
        /// <exception cref="InvalidOperationException">The number of periods could not be calculated.</exception>
        public static uint NumberOfPeriods(decimal rate, decimal payment, decimal currentBalance, decimal futureBalance = decimal.Zero, bool payAtBeginningOfPeriod = false)
        {
            Contract.Requires <ArgumentOutOfRangeException>(rate >= 0, "Rate may not be less than zero.");
            VerifyMoneyArgument(payment, "payment");
            VerifyMoneyArgument(currentBalance, "currentBalance");
            VerifyMoneyArgument(futureBalance, "futureBalance");

            var result = Exact.NumberOfPeriods(rate, -payment, currentBalance, futureBalance, payAtBeginningOfPeriod);

            if (result < decimal.Zero)
            {
                var e = new InvalidOperationException("The number of periods could not be calculated.");
                e.Data["rate"]                   = rate;
                e.Data["payment"]                = payment;
                e.Data["currentBalance"]         = currentBalance;
                e.Data["futureBalance"]          = futureBalance;
                e.Data["payAtBeginningOfPeriod"] = payAtBeginningOfPeriod;
                e.Data["result"]                 = result;
                throw e;
            }

            try
            {
                return(checked ((uint)Math.Ceiling(result)));
            }
            catch (OverflowException ex)
            {
                var e = new InvalidOperationException("The number of periods could not be calculated.", ex);
                e.Data["rate"]                   = rate;
                e.Data["payment"]                = payment;
                e.Data["currentBalance"]         = currentBalance;
                e.Data["futureBalance"]          = futureBalance;
                e.Data["payAtBeginningOfPeriod"] = payAtBeginningOfPeriod;
                e.Data["result"]                 = result;
                throw e;
            }
        }