TheAlgorithms/C-Sharp · error · ArgumentException

Discount rate cannot be negative

Error message

Discount rate cannot be negative

What it means

PresentValue.Calculate computes the present value of a cash flow series discounted at the given rate. A negative discount rate is rejected with ArgumentException "Discount rate cannot be negative" because the discounting formula is not meaningful for negative rates in this implementation.

Solutions

  1. Pass a non-negative discount rate (use 0 for no discounting).
  2. Clamp the rate before the call: Math.Max(0, discountRate).
  3. If a negative rate is legitimate for your analysis, implement the formula yourself instead of using this helper.
  4. Check the rate's units — convert a percentage like 5 to 0.05, and verify sign conventions in upstream calculations.

Example fix

// before
var pv = PresentValue.Calculate(discountRate, cashFlows); // discountRate = -0.03
// after
var rate = Math.Max(0, discountRate);
var pv = PresentValue.Calculate(rate, cashFlows);
Defensive patterns

Strategy: validation

Validate before calling

if (discountRate < 0)
    throw new ArgumentOutOfRangeException(nameof(discountRate), "Discount rate must be non-negative.");
if (cashFlows == null || cashFlows.Count == 0)
    throw new ArgumentException("Cash flows list cannot be empty.");

Type guard

static bool IsValidPresentValueInput(double discountRate, List<double> cashFlows) =>
    discountRate >= 0 && cashFlows != null && cashFlows.Count > 0;

Try / catch

try
{
    var pv = PresentValue.Calculate(discountRate, cashFlows);
}
catch (ArgumentException ex)
{
    logger.LogWarning(ex, "Invalid present-value input (rate={Rate})", discountRate);
    throw new InvalidOperationException("Provide a non-negative discount rate and at least one cash flow.", ex);
}

Prevention

When it happens

Trigger: Calling PresentValue.Calculate with discountRate < 0, e.g. Calculate(-0.05, new List<double> { 100, 200 }) — throws ArgumentException. Also happens when the rate is computed from other data (spread, difference of rates) and turns out negative.

Common situations: Passing a percentage (e.g. -5) instead of a signed decimal rate; computing the rate dynamically from market data that went negative; unit signs confusion when a negative rate was intended as 'add 5%' but supplied as -0.05.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of TheAlgorithms/C-Sharp@96e2905cab (2026-09-13). Data as JSON: /api/errors/feda6727eeeb343d. Report an issue: GitHub.

Appendix: source

Thrown at Algorithms/Financial/PresentValue.cs:12

namespace Algorithms.Financial;

/// <summary>
/// PresentValue is the value of an expected income stream determined as of the date of valuation.
/// </summary>
public static class PresentValue
{
    public static double Calculate(double discountRate, List<double> cashFlows)
    {
        if (discountRate < 0)
        {
            throw new ArgumentException("Discount rate cannot be negative");
        }

        if (cashFlows.Count == 0)
        {
            throw new ArgumentException("Cash flows list cannot be empty");
        }

        double presentValue = cashFlows.Select((t, i) => t / Math.Pow(1 + discountRate, i)).Sum();

        return Math.Round(presentValue, 2);
    }
}

View on GitHub (pinned to 96e2905cab)