TheAlgorithms/C-Sharp · error · ArgumentException

The value for some a_i is smaller than 0.

Error message

The value {listOfAs.First(x => x < 0)} for some a_i is smaller than 0.

What it means

The CRT construction assumes each remainder a_i is a non-negative residue. CheckRequirements throws ArgumentException identifying the first negative a_i, since a negative remainder falls outside the canonical residue range for its modulus.

Solutions

  1. Normalize each remainder into [0, n_i) before calling Compute: a = ((a % n) + n) % n.
  2. Validate listOfAs for negatives in the caller and reject or normalize them with a clear message.
  3. Fix the upstream remainder computation to use a proper mathematical mod operation.

Example fix

// before
ChineseRemainderTheorem.Compute(new List<long> { -1 }, new List<long> { 5 }); // throws

// after
var normalized = listOfAs.Zip(listOfNs, (a, n) => ((a % n) + n) % n).ToList();
ChineseRemainderTheorem.Compute(normalized, listOfNs);
Defensive patterns

Strategy: validation

Validate before calling

var normalized = listOfAs.Zip(listOfNs, (a, n) => ((a % n) + n) % n).ToList();
ChineseRemainderTheorem.Compute(normalized, listOfNs);

Type guard

static bool HasNonNegativeRemainders(List<long> as_) => as_ != null && as_.All(a => a >= 0);

Try / catch

try
{
    var result = ChineseRemainderTheorem.Compute(listOfAs, listOfNs);
}
catch (ArgumentException ex) when (ex.Message.Contains("some a_i is smaller than 0"))
{
    logger.LogError("Negative remainder in CRT input: {Msg}", ex.Message);
    throw;
}

Prevention

When it happens

Trigger: Calling Compute where any entry of listOfAs is negative, e.g. remainders taken directly from signed arithmetic like -3 mod 5 instead of normalizing to 2.

Common situations: Users entering remainders as negative numbers ("x ≡ -1 (mod 5)"); computing remainders in C# where % can return negative values for negative operands.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at Algorithms/ModularArithmetic/ChineseRemainderTheorem.cs:134

    /// </summary>
    /// <param name="listOfAs">An ordered list of a_0, a_1, ..., a_k.</param>
    /// <param name="listOfNs">An ordered list of n_0, n_1, ..., n_k.</param>
    /// <exception cref="ArgumentException">If any of the requirements is not fulfilled.</exception>
    private static void CheckRequirements(List<long> listOfAs, List<long> listOfNs)
    {
        if (listOfAs == null || listOfNs == null || listOfAs.Count != listOfNs.Count)
        {
            throw new ArgumentException("The parameters 'listOfAs' and 'listOfNs' must not be null and have to be of equal length!");
        }

        if (listOfNs.Any(x => x <= 1))
        {
            throw new ArgumentException($"The value {listOfNs.First(x => x <= 1)} for some n_i is smaller than or equal to 1.");
        }

        if (listOfAs.Any(x => x < 0))
        {
            throw new ArgumentException($"The value {listOfAs.First(x => x < 0)} for some a_i is smaller than 0.");
        }

        // Check if all pairs of (n_i, n_j) are coprime:
        for (var i = 0; i < listOfNs.Count; i++)
        {
            for (var j = i + 1; j < listOfNs.Count; j++)
            {
                long gcd;
                if ((gcd = ExtendedEuclideanAlgorithm.Compute(listOfNs[i], listOfNs[j]).Gcd) != 1L)
                {
                    throw new ArgumentException($"The GCD of n_{i} = {listOfNs[i]} and n_{j} = {listOfNs[j]} equals {gcd} and thus these values aren't coprime.");
                }
            }
        }
    }

    /// <summary>
    /// Checks the requirements for the algorithm and throws an ArgumentException if they are not being met.

View on GitHub (pinned to 96e2905cab)