public function ceil(DecimalNumber $number, $precision)
    {
        $precision = $this->sanitizePrecision($precision);

        if ($number->getPrecision() <= $precision) {
            return $number;
        }

        if ($number->isNegative()) {
            // ceil works exactly as truncate for negative numbers
            return $this->truncate($number, $precision);
        }

        /**
         * The principle for ceil is the following:
         *
         * let X = number to round
         *     P = number of decimal digits that we want
         *     D = digit from the fractional part at index P
         *
         * if D > 0, ceil(X, P) = truncate(X + 10^(-P), P)
         * if D = 0, ceil(X, P) = truncate(X, P)
         */

        if ($precision > 0) {
            // we know that D > 0, because we have already checked that the number's precision
            // is greater than the target precision
            $numberToAdd = '0.' . str_pad('1', $precision, '0', STR_PAD_LEFT);
        } else {
            $numberToAdd = '1';
        }

        return $this
            ->truncate($number, $precision)
            ->plus(new DecimalNumber($numberToAdd));
    }