public function computeWithoutBcMath(DecimalNumber $a, DecimalNumber $b)
    {
        if ($a->isNegative()) {
            if ($b->isNegative()) {
                // if both numbers are negative,
                // we can just add them as positive numbers and then invert the sign
                // f(x, y) = -(|x| + |y|)
                // eg. f(-1, -2) = -(|-1| + |-2|) = -3
                // eg. f(-2, -1) = -(|-2| + |-1|) = -3
                return $this
                    ->computeWithoutBcMath($a->toPositive(), $b->toPositive())
                    ->invert();
            }
            // if the number is negative and the addend positive,
            // perform an inverse subtraction by inverting the terms
            // f(x, y) = y - |x|
            // eg. f(-2, 1) = 1 - |-2| = -1
            // eg. f(-1, 2) = 2 - |-1| = 1
            // eg. f(-1, 1) = 1 - |-1| = 0
            return $b->minus(
                $a->toPositive()
            );
        }

        if ($b->isNegative()) {
            // if the number is positive and the addend is negative
            // perform subtraction instead: 2 - 1
            // f(x, y) = x - |y|
            // f(2, -1) = 2 - |-1| = 1
            // f(1, -2) = 1 - |-2| = -1
            // f(1, -1) = 1 - |-1| = 0
            return $a->minus(
                $b->toPositive()
            );
        }

        // optimization: 0 + x = x
        if ('0' === (string) $a) {
            return $b;
        }

        // optimization: x + 0 = x
        if ('0' === (string) $b) {
            return $a;
        }

        // pad coefficients with leading/trailing zeroes
        list($coeff1, $coeff2) = $this->normalizeCoefficients($a, $b);

        // compute the coefficient sum
        $sum = $this->addStrings($coeff1, $coeff2);

        // both signs are equal, so we can use either
        $sign = $a->getSign();

        // keep the bigger exponent
        $exponent = max($a->getExponent(), $b->getExponent());

        return new DecimalNumber($sign . $sum, $exponent);
    }