{"record":{"id":"ac17bd732814adcc","repo":"TheAlgorithms/Java","slug":"n-or-k-can-t-be-negative","errorCode":null,"errorMessage":"n or k can't be negative","messagePattern":"n or k can't be negative","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/maths/Combinations.java","lineNumber":49,"sourceCode":"        return factorial(n) / (factorial(k) * factorial(n - k));\n    }\n\n    /**\n     * The above method can exceed limit of long (overflow) when factorial(n) is\n     * larger than limits of long variable. Thus even if nCk is within range of\n     * long variable above reason can lead to incorrect result. This is an\n     * optimized version of computing combinations. Observations: nC(k + 1) = (n\n     * - k) * nCk / (k + 1) We know the value of nCk when k = 1 which is nCk = n\n     * Using this base value and above formula we can compute the next term\n     * nC(k+1)\n     *\n     * @param n\n     * @param k\n     * @return nCk\n     */\n    public static long combinationsOptimized(int n, int k) {\n        if (n < 0 || k < 0) {\n            throw new IllegalArgumentException(\"n or k can't be negative\");\n        }\n        if (n < k) {\n            throw new IllegalArgumentException(\"n can't be smaller than k\");\n        }\n        // nC0 is always 1\n        long solution = 1;\n        for (int i = 0; i < k; i++) {\n            solution = (n - i) * solution / (i + 1);\n        }\n        return solution;\n    }\n}\n","sourceCodeStart":31,"sourceCodeEnd":62,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/maths/Combinations.java#L31-L62","documentation":"Thrown by Combinations.combinationsOptimized when n < 0 or k < 0. Binomial coefficients C(n,k) are defined for non-negative n and k; negative values have no combinatorial meaning. The guard fires before the n < k check, so it specifically catches negative inputs as distinct from the ordering error.","triggerScenarios":"Calling combinationsOptimized(-1, 2), combinationsOptimized(5, -1), or both negative. Triggered when either parameter is derived from subtraction that can underflow, or parsed from unvalidated input.","commonSituations":"n or k computed as differences that can go negative; UI inputs accepting negative numbers; passing k larger than expected and then subtracting to a negative index.","solutions":["Pass non-negative n and k (>= 0).","Validate both at the caller: if (n < 0 || k < 0) reject before calling.","Clamp derived values with Math.max(0, ...) where a negative result indicates an empty selection."],"exampleFix":"// before\nlong c = Combinations.combinationsOptimized(total - picked, spare);\n\n// after\nlong c = Combinations.combinationsOptimized(Math.max(0, total - picked), Math.max(0, spare));","handlingStrategy":"validation","validationCode":"if (n < 0 || k < 0) {\n    throw new IllegalArgumentException(\"n and k must be >= 0\");\n}\nCombinations.combinationsOptimized(n, k);","typeGuard":"static boolean areNonNegative(int n, int k) { return n >= 0 && k >= 0; }","tryCatchPattern":null,"preventionTips":["Bound k against n and against zero before calling.","Use Math.max(0, ...) on values derived from subtraction.","Validate UI inputs that accept signed integers."],"tags":["validation","combinatorics","precondition"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}