Skip to content

Number::format() ignores $precision when $maxPrecision is set #58517

@LWlook

Description

@LWlook

Laravel Version

12.48.1

PHP Version

8.4

Description

The Number::format() method has unexpected behavior where the $precision parameter is completely ignored if $maxPrecision is provided. This is counterintuitive because:

  1. $precision comes before $maxPrecision in the parameter list
  2. A later parameter should not completely override an earlier one
  3. I would expect both parameters to work together (min and max precision)

Current Behavior

8ab2184#diff-2866de1046fe4e657a94ff101ff6b049818966c89117bc87a9d2017c63315214R35-R40

use Illuminate\Support\Number;

// This returns "5,1" instead of "5,10"
Number::format(5.1, precision: 2, maxPrecision: 2, locale: 'de');

The $precision parameter is completely ignored because $maxPrecision is set.

Expected Behavior

When both $precision and $maxPrecision are provided:

  1. $precision should set the minimum fraction digits
  2. $maxPrecision should set the maximum fraction digits

This would allow proper formatting like "5,10" while still capping at the maximum.

Proposed Solution

if (! is_null($precision)) {
    $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $precision);
}

if (! is_null($maxPrecision)) {
    $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxPrecision);
} elseif (! is_null($precision)) {
    // If only precision is set, use it for both min and max (current behavior)
    $formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
}

This would:

  • Always respect $precision as minimum fraction digits when provided
  • Maintain backward compatibility when only $precision or only $maxPrecision is set
  • Allow both parameters to work together logically

Steps To Reproduce

use Illuminate\Support\Number;

// Test case 1: Only precision
echo Number::format(5.1, precision: 2, locale: 'de');
// Current: "5,10" ✓
// Expected: "5,10" ✓

// Test case 2: Both precision and maxPrecision
echo Number::format(5.1, precision: 2, maxPrecision: 4, locale: 'de');
// Current: "5,1" ❌ (precision ignored)
// Expected: "5,10" ✓ (min 2, max 4 decimals)

// Test case 3: Value with more decimals than max
echo Number::format(5.12345, precision: 2, maxPrecision: 3, locale: 'de');
// Expected: "5,123" ✓ (respects max)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions