TheAlgorithms/Java · error · IllegalArgumentException

n must be positive and odd.

Error message

n must be positive and odd.

What it means

Thrown by EulerPseudoprime.jacobiSymbol when n is not positive or not odd. The Jacobi symbol (a/n) is defined for odd positive n; even or non-positive n have no Jacobi symbol under the standard definition. The implementation's reduction loop (halving a, checking n mod 8) assumes n is odd, so the guard prevents mathematically meaningless and incorrect computation.

Source

Thrown at src/main/java/com/thealgorithms/maths/EulerPseudoprime.java:69

            BigInteger exp = n.subtract(BigInteger.ONE).divide(BigInteger.TWO);
            BigInteger modExp = a.modPow(exp, n);

            // Euler's criterion: a^((n-1)/2) ≡ (a/n) (mod n)
            if (!modExp.equals(jacobi.mod(n))) {
                return false; // definitely composite
            }
        }
        return true; // probably prime
    }

    /**
     * Computes the Jacobi symbol (a/n).
     * Assumes n is positive and odd.
     */
    public static int jacobiSymbol(BigInteger a, BigInteger n) {
        if (n.signum() <= 0 || n.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
            throw new IllegalArgumentException("n must be positive and odd.");
        }

        int result = 1;
        a = a.mod(n);

        while (a.compareTo(BigInteger.ZERO) != 0) {
            while (a.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
                a = a.divide(BigInteger.TWO);
                BigInteger nMod8 = n.mod(BigInteger.valueOf(8));
                if (nMod8.equals(BigInteger.valueOf(3)) || nMod8.equals(BigInteger.valueOf(5))) {
                    result = -result;
                }
            }

            BigInteger temp = a;
            a = n;
            n = temp;

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Pass an odd positive BigInteger for n, e.g. jacobiSymbol(a, BigInteger.valueOf(9)).
  2. Validate n at the caller: ensure n.signum() > 0 and n is odd before calling.
  3. If you need Legendre symbols, ensure n is an odd prime.

Example fix

// before
int j = EulerPseudoprime.jacobiSymbol(a, BigInteger.valueOf(8)); // even => throws

// after
int j = EulerPseudoprime.jacobiSymbol(a, BigInteger.valueOf(9));
Defensive patterns

Strategy: validation

Validate before calling

if (n.signum() <= 0 || n.mod(BigInteger.TWO).equals(BigInteger.ZERO)) {
    throw new IllegalArgumentException("Jacobi n must be positive and odd");
}
EulerPseudoprime.jacobiSymbol(a, n);

Type guard

static boolean isOddPositive(BigInteger n) {
    return n.signum() > 0 && n.testBit(0);
}

Prevention

When it happens

Trigger: Calling jacobiSymbol(a, n) with n <= 0 (e.g. BigInteger.ZERO or a negative), or n even (e.g. BigInteger.valueOf(2), 4, 10). Common when n is an arbitrary modulus not constrained to odd primes, or when n comes from user input.

Common situations: Using a general modulus instead of an odd one; feeding an even composite; n parsed from input without parity validation; confusing Jacobi with a general modular operation.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/67c4c76946e17d59. Report an issue: GitHub.