TheAlgorithms/Java · error · IllegalArgumentException

Input cannot be negative

Error message

Input cannot be negative

What it means

Thrown by HighestSetBit.findHighestSetBit(int) when the input integer is negative. The method locates the index of the highest (most-significant) set bit in a non-negative value, returning Optional.empty() for 0. Negative values are rejected because in Java's two's complement encoding bit 31 is always set, which makes the 'highest set bit' result meaningless and surprising, so the library mandates non-negative input.

Source

Thrown at src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java:39

    private HighestSetBit() {
    }

    /**
     * Finds the highest (most significant) set bit in the given integer.
     * The method returns the position (index) of the highest set bit as an {@link Optional}.
     *
     * - If the number is 0, no bits are set, and the method returns {@link Optional#empty()}.
     * - If the number is negative, the method throws {@link IllegalArgumentException}.
     *
     * @param num The input integer for which the highest set bit is to be found. It must be non-negative.
     * @return An {@link Optional} containing the index of the highest set bit (zero-based).
     *         Returns {@link Optional#empty()} if the number is 0.
     * @throws IllegalArgumentException if the input number is negative.
     */
    public static Optional<Integer> findHighestSetBit(int num) {
        if (num < 0) {
            throw new IllegalArgumentException("Input cannot be negative");
        }

        if (num == 0) {
            return Optional.empty();
        }

        int position = 0;
        while (num > 0) {
            num >>= 1;
            position++;
        }

        return Optional.of(position - 1); // Subtract 1 to convert to zero-based index
    }
}

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Guard the call: only invoke findHighestSetBit when num >= 0.
  2. If the value is logically unsigned, convert with Integer.toUnsignedLong and operate on that, or mask the sign bit consciously.
  3. If you genuinely need the highest set bit of a negative int, reconsider — in two's complement it is always bit 31, so handle that case explicitly instead of relying on this method.

Example fix

// before
int pos = HighestSetBit.findHighestSetBit(a - b).orElse(-1);

// after
int diff = a - b;
int pos = diff >= 0 ? HighestSetBit.findHighestSetBit(diff).orElse(-1) : -1;
Defensive patterns

Strategy: validation

Validate before calling

if (num < 0) {
    throw new IllegalArgumentException("num must be non-negative, got " + num);
}
Optional<Integer> result = HighestSetBit.findHighestSetBit(num);

Type guard

// Java has no runtime type guard; use a static helper
static boolean isFindable(int num) { return num >= 0; }

Try / catch

try {
    Optional<Integer> pos = HighestSetBit.findHighestSetBit(num);
} catch (IllegalArgumentException e) {
    // handle negative input: log and use a sentinel
    pos = Optional.empty();
}

Prevention

When it happens

Trigger: Calling findHighestSetBit(num) with any value where num < 0 (e.g. -1, -42, Integer.MIN_VALUE). This includes results of subtractions that underflow past zero and ints read from a byte stream that are logically unsigned but Java interprets as signed.

Common situations: Reading a magnitude from a network/byte buffer where the sign bit is set; arithmetic like a - b where b > a; converting a long mask to int without checking range; off-by-one loops that decrement past zero.

Related errors


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