PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Calculation\Exception

#DIV/0!

#DIV/0!

Error message

#DIV/0!

What it means

MathTrig\Helpers::validateNotZero() rejects a zero divisor/denominator with ExcelError::DIV0() ('#DIV/0!'). Its call sites are MathTrig\Operations::mod() (MOD) and MathTrig\Operations::quotient() (QUOTIENT), replicating Excel's behaviour for =MOD(x,0) and =QUOTIENT(x,0). The engine converts the thrown Calculation\Exception into the cell value '#DIV/0!'; direct PHP calls see the raw exception.

Source

Thrown at src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php:89

    public static function validatePositive(float|int $number, ?string $except = null): void
    {
        if ($number > 0) {
            return;
        }

        throw new Exception($except ?? ExcelError::NAN());
    }

    /**
     * Confirm number != 0.
     */
    public static function validateNotZero(float|int $number): void
    {
        if ($number) {
            return;
        }

        throw new Exception(ExcelError::DIV0());
    }

    public static function returnSign(float $number): int
    {
        return $number ? (($number > 0) ? 1 : -1) : 0;
    }

    public static function getEven(float $number): float
    {
        $significance = 2 * self::returnSign($number);

        return $significance ? (ceil($number / $significance) * $significance) : 0;
    }

    /**
     * Return NAN or value depending on argument.
     */
    public static function numberOrNan(float $result): float|string

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Guard the divisor in the formula: =IF(B1<>0, MOD(A1,B1), 0) or wrap with =IFERROR(MOD(A1,B1),"")
  2. Fix the source data so the divisor cell is non-zero (or explicitly 0-handled)
  3. Pre-check values in PHP before writing the formula if you generate formulas programmatically
  4. When calling Operations::mod()/quotient() directly, test $divisor != 0 first or catch Calculation\Exception

Example fix

// before
$sheet->getCell('C1')->setValue('=MOD(A1,B1)'); // B1 = 0 -> #DIV/0!

// after
$sheet->getCell('C1')->setValue('=IF(B1=0, 0, MOD(A1,B1))');
Defensive patterns

Strategy: validation

Validate before calling

if (!is_numeric($divisor) || (float) $divisor === 0.0) {
    return 0; // or skip / report
}
$result = \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Operations::quotient($numerator, $divisor);

Type guard

function isNonZeroNumber(mixed $d): bool
{
    return (is_int($d) || is_float($d)) && $d !== 0;
}

Try / catch

try {
    $r = Operations::mod($dividend, $divisor);
} catch (\PhpOffice\PhpSpreadsheet\Calculation\Exception $e) {
    if ($e->getMessage() === '#DIV/0!') { $r = 0; } else { throw $e; }
}

Prevention

When it happens

Trigger: =MOD(10,0) or =QUOTIENT(5,0); MOD/QUOTIENT where the divisor cell is empty, evaluates to 0, or a referenced chain yields 0 (e.g. =MOD(A1,B1-B2) with B1=B2); calling Operations::mod(10, 0) directly.

Common situations: Divisor columns containing blanks or zero-valued rows in imported CSV/Xlsx data; downstream formulas where a subtraction used as the divisor collapses to zero; data-entry spreadsheets where the divisor is only filled in later; migrating formulas that silently relied on PHP's ownDivision semantics.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/238f4b7206757de6. Report an issue: GitHub.