brick/math
Arbitrary-precision math for PHP. Work with big integers, decimals, and rational numbers via a clean OOP API. Optimized with GMP or BCMath when available, with automatic runtime selection. Requires PHP 8.2+ (older versions available).
BigInteger::of(), BigDecimal::of()) simplify adoption. No ORM or service container integration needed.RoundingNecessaryException early).0.x.y with backward-incompatible jumps (e.g., 0.15.0 removed float support). Lock to ^0.17 to mitigate.BigDecimal::fromFloatExact() exposes IEEE-754 quirks (e.g., 0.1 → 0.10000000000000000555...). Requires explicit handling in user-facing APIs.RoundingNecessaryException). Requires robust error handling in business logic.float/int for exactness, or supplementing them (e.g., for display only)?RoundingMode::Bankers) vs. scientific precision.php-gmp, bcmath native functions).MathException be mapped to Laravel’s Handler (e.g., convert to HttpResponse)?422 Unprocessable Entity for RoundingNecessaryException in APIs.BigInteger::nthRoot(-1, 2)) in CI?brick/math to a specific patch version (e.g., 0.17.2) or use ^0.17?0.18.0).BigDecimal::dividedBy(string|BigDecimal $divisor, int $scale)).brick/math in FormRequest rules (e.g., validate BigDecimal precision).assertEquals(0.1 + 0.2, 0.3) with BigDecimal assertions.Money with BigDecimal for arbitrary-precision currency.BigInteger for time-based calculations (e.g., Unix timestamps with millisecond precision).float-intensive class (e.g., OrderTotalCalculator) with BigDecimal.0.1 + 0.2 != 0.3).PaymentService, TaxCalculator).BigDecimal::fromFloatShortest() for legacy float inputs.string for numeric fields (e.g., "amount": "123.456").BigDecimal inputs (e.g., reject 1.23e+20).BigDecimal as string in PostgreSQL (use numeric for hybrid approaches).float/decimal columns to prevent rounding.float/int logic in adapters (e.g., FloatToBigDecimal::convert()).class LegacyFloatAdapter {
public static function toBigDecimal(float $value): BigDecimal {
return BigDecimal::fromFloatExact($value);
}
}
composer.json extras:
"config": {
"preferred-install": "dist",
"platform-check": {
"php": "8.2",
"ext-gmp": "enabled",
"ext-bcmath": "enabled"
}
}
pure-php branch if extensions are unavailable./checkout) until performance is validated.BigDecimal to test rounding behavior.BigInteger::of("9999999999999999999999999999999999999999999")).config('math.use_brick_math') for gradual adoption.BigDecimal logging.brick/math for breaking changes (e.g., 0.18.0).composer why-not brick/math:0.18.0 to assess risks.BigDecimal::of("1.01") vs. BigDecimal::of(1.01)).## Brick Math Best Practices
- Use `BigDecimal::fromFloatShortest()` for legacy `float` inputs.
- Avoid chaining operations in loops (e.g., `$result->plus($x)->minus($y)` creates intermediate objects).
simPod/phpstan-brick-math for static analysis.float to BigDecimal incrementally.0.1 + 0.2 == 0.3. Document this explicitly.Xdebug + Blackfire.BigNumber instances are JSON-serializable.MathDebugger service to log operations:
class MathDebugger {
public static function log(BigNumber $number, string $operation, BigNumber|int|string $operand): void {
\Log::debug("Math: {$number} {$operation} {$operand} = {$number->{$operation}($operand)}");
}
}
$x->plus($y) vs. $x += $y).RoundingNecessaryException vs. DivisionByZeroException).How can I help you explore Laravel packages today?