dm/decimal-calculator-bundle
Installation Add the bundle via Composer:
composer require dm/decimal-calculator-bundle
Register the bundle in config/bundles.php (Symfony 5+):
return [
// ...
Dm\DecimalCalculatorBundle\DmDecimalCalculatorBundle::class => ['all' => true],
];
First Use Case Inject the service in a controller or service:
use Dm\DecimalCalculatorBundle\Service\DecimalCalculator;
class MyController extends AbstractController
{
public function index(DecimalCalculator $calculator)
{
$result = $calculator->add('123.456789', '987.654321');
return new Response($result); // Outputs: 1111.111110
}
}
Twig Integration Use the Twig filter in templates:
{{ '123.456789'|decimal_add('987.654321') }} {# Outputs: 1111.111110 #}
Available filters/tags:
decimal_add, decimal_subtract, decimal_multiply, decimal_dividedecimal_round, decimal_ceil, decimal_floorPrecision Control
Configure default precision in config/packages/dm_decimal_calculator.yaml:
dm_decimal_calculator:
precision: 20 # Default precision for all operations
Override per operation:
$calculator->add('1.234', '5.678', 15); // 15-decimal precision
Common Workflows
$tax = $calculator->multiply($subtotal, '1.21'); // 21% tax
$total = $calculator->add($subtotal, $tax);
$converted = $calculator->divide($amount, '1.15'); // USD to EUR (1.15 exchange rate)
Chaining Operations Reuse the service across methods:
class OrderService {
public function __construct(private DecimalCalculator $calculator) {}
public function calculateTotal(float $price, int $quantity, float $taxRate): string
{
$subtotal = $this->calculator->multiply($price, $quantity);
$tax = $this->calculator->multiply($subtotal, $taxRate);
return $this->calculator->add($subtotal, $tax);
}
}
{% set discount = '15.5' %}
{% set finalPrice = product.price|decimal_subtract(product.price|decimal_multiply(discount)|decimal_divide('100')) %}
{% if order.total|decimal_gt('1000') %}
<p class="highlight">Eligible for free shipping!</p>
{% endif %}
$amount = $request->input('amount');
if (!preg_match('/^\d+(\.\d+)?$/', $amount)) {
throw new \InvalidArgumentException('Invalid decimal format');
}
decimal(20, 10) in MySQL) to preserve precision:
$dbValue = $calculator->multiply('1.23456789', '9.87654321'); // Store as string
Precision Mismatch
$calculator->add('0.1', '0.2', 20); // Avoids floating-point errors
Twig Caching
php bin/console cache:clear
String vs. Float Inputs
1.23) may lose precision.$calculator->add('1.23', '4.56'); // Correct
$calculator->add(1.23, 4.56); // Risky (float conversion)
BCMath Dependencies
php.ini (extension=php_bcmath.dll).if (!extension_loaded('bcmath')) {
throw new \RuntimeException('BCMath extension is required');
}
$step1 = $calculator->multiply('100', '1.2');
$step2 = $calculator->add($step1, '5');
logger()->info("Step 1: {$step1}, Step 2: {$step2}");
$this->assertEquals('0.0000000001', $calculator->add('0.00000000005', '0.00000000005'));
Custom Precision Strategies
Override the default BN-PHP implementation by extending the service:
class CustomCalculator extends DecimalCalculator {
protected function getPrecision(): int {
return 30; // Custom default
}
}
Register as a service in services.yaml:
services:
App\Service\CustomCalculator:
tags: ['dm_decimal_calculator.calculator']
Additional Operations Extend the Twig extension for custom functions:
// src/Twig/DmDecimalCalculatorExtension.php
public function getFunctions() {
return [
new \Twig\TwigFunction('decimal_percentage', [$this->calculator, 'calculatePercentage']),
];
}
Fallback for BCMath Implement a fallback (e.g., GMP) if BCMath is unavailable:
dm_decimal_calculator:
fallback: gmp # Requires custom implementation
How can I help you explore Laravel packages today?