{"record":{"id":"e43e306b52b63d89","repo":"PHPOffice/PhpSpreadsheet","slug":"num-e43e30","errorCode":"#NUM!","errorMessage":"#NUM!","messagePattern":"#NUM!","errorType":"exception","errorClass":"PhpOffice\\PhpSpreadsheet\\Calculation\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php","lineNumber":65,"sourceCode":"            return $substitute;\n        }\n        if (is_numeric($number)) {\n            return 0 + $number;\n        }\n\n        throw new Exception(ExcelError::throwError($number));\n    }\n\n    /**\n     * Confirm number >= 0.\n     */\n    public static function validateNotNegative(float|int $number, ?string $except = null): void\n    {\n        if ($number >= 0) {\n            return;\n        }\n\n        throw new Exception($except ?? ExcelError::NAN());\n    }\n\n    /**\n     * Confirm number > 0.\n     */\n    public static function validatePositive(float|int $number, ?string $except = null): void\n    {\n        if ($number > 0) {\n            return;\n        }\n\n        throw new Exception($except ?? ExcelError::NAN());\n    }\n\n    /**\n     * Confirm number != 0.\n     */\n    public static function validateNotZero(float|int $number): void","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/PHPOffice/PhpSpreadsheet/blob/65b080eef4d9fd11a5796135ab145883e5c3d6a6/src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php#L47-L83","documentation":"MathTrig\\Helpers::validateNotNegative() (MathTrig/Helpers.php:59-66) is the domain guard for functions requiring a non-negative number: it throws #NUM! by default, or a caller-supplied $except error string. Callers include SQRT (Sqrt::funcSqrt), FACT/FACTDOUBLE (Factorial), GCD/LCM values, COMBIN/COMBINX counts, and RAND's max-min span (RANDBETWEEN with min > max).","triggerScenarios":"SQRT(-1); FACT(-5); GCD(-12, 8); RANDBETWEEN(100, 50) where the negative span (max-min) reaches the guard.","commonSituations":"User-supplied quantities or durations that can go negative; square roots of differences (a-b with b > a); random ranges supplied in the wrong order; date/time deltas computed backwards.","solutions":["Check $value >= 0 before calling these functions","Use abs() only when the domain genuinely means magnitude","Supply min/max to RANDBETWEEN in the correct (min, max) order","Validate numeric bounds at the input boundary, not inside spreadsheet formulas"],"exampleFix":"// before\n$result = Sqrt::funcSqrt($a - $b); // negative when $b > $a -> '#NUM!'\n\n// after: guard the domain, then choose a policy\n$delta = $a - $b;\nif ($delta < 0) {\n    throw new InvalidArgumentException('cannot take SQRT of a negative difference');\n}\n$result = Sqrt::funcSqrt($delta);","handlingStrategy":"validation","validationCode":"if ((float) $number < 0.0) {\n    throw new InvalidArgumentException('value must be non-negative for this function');\n}\n$result = Sqrt::funcSqrt($number);","typeGuard":"function isNonNegativeNumber(mixed $value): bool\n{\n    return is_numeric($value) && (float) $value >= 0.0;\n}","tryCatchPattern":"$result = Factorial::funcFact($value);\nif ($result === '#NUM!' && (float) $value < 0.0) {\n    // negative input reached a non-negative-only domain (SQRT/FACT/GCD/LCM/COMBIN)\n}","preventionTips":["Guard differences before SQRT: compute abs() only if magnitude is intended","Order RANDBETWEEN arguments (min, max)","Validate user-entered counts/durations as >= 0 at input time"],"tags":["phpspreadsheet","php","excel","math","sqrt","fact","num-error","domain-error"],"backgroundTag":"excel-num-error","analyzedSha":"65b080eef4d9fd11a5796135ab145883e5c3d6a6","analyzedAt":"2026-08-17T05:40:41.646Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}