protected function formatNumber($number, NumberFormat $numberFormat, array $options = [])
    {
        $parsedPattern = $this->getParsedPattern($numberFormat, $options['style']);
        // Start by rounding the number, if rounding is enabled.
        if (is_int($options['rounding_mode'])) {
            $number = Calculator::round($number, $options['maximum_fraction_digits'], $options['rounding_mode']);
        }
        $negative = (Calculator::compare('0', $number, 12) == 1);
        // Ensure that the value is positive and has the right number of digits.
        $signMultiplier = $negative ? '-1' : '1';
        $number = bcdiv($number, $signMultiplier, $options['maximum_fraction_digits']);
        // Split the number into major and minor digits.
        $numberParts = explode('.', $number);
        $majorDigits = $numberParts[0];
        // Account for maximumFractionDigits = 0, where the number won't
        // have a decimal point, and $numberParts[1] won't be set.
        $minorDigits = isset($numberParts[1]) ? $numberParts[1] : '';

        if ($options['use_grouping'] && $parsedPattern->isGroupingUsed()) {
            // Reverse the major digits, since they are grouped from the right.
            $majorDigits = array_reverse(str_split($majorDigits));
            // Group the major digits.
            $groups = [];
            $groups[] = array_splice($majorDigits, 0, $parsedPattern->getPrimaryGroupSize());
            while (!empty($majorDigits)) {
                $groups[] = array_splice($majorDigits, 0, $parsedPattern->getSecondaryGroupSize());
            }
            // Reverse the groups and the digits inside of them.
            $groups = array_reverse($groups);
            foreach ($groups as &$group) {
                $group = implode(array_reverse($group));
            }
            // Reconstruct the major digits.
            $majorDigits = implode(',', $groups);
        }

        if ($options['minimum_fraction_digits'] < $options['maximum_fraction_digits']) {
            // Strip any trailing zeroes.
            $minorDigits = rtrim($minorDigits, '0');
            if (strlen($minorDigits) < $options['minimum_fraction_digits']) {
                // Now there are too few digits, re-add trailing zeroes
                // until the desired length is reached.
                $neededZeroes = $options['minimum_fraction_digits'] - strlen($minorDigits);
                $minorDigits .= str_repeat('0', $neededZeroes);
            }
        }

        // Assemble the final number and insert it into the pattern.
        $number = strlen($minorDigits) ? $majorDigits . '.' . $minorDigits : $majorDigits;
        $pattern = $negative ? $parsedPattern->getNegativePattern() : $parsedPattern->getPositivePattern();
        $number = preg_replace('/#(?:[\.,]#+)*0(?:[,\.][0#]+)*/', $number, $pattern);
        $number = $this->localizeNumber($number, $numberFormat);

        return $number;
    }