Maison >développement back-end >tutoriel php >Gestion des calculs décimaux en PHP avec la nouvelle API d'objet BCMath
Publié à l'origine sur le blog de Takeshi Yu.
Un calcul numérique précis est primordial dans les applications d'entreprise, en particulier celles traitant de la finance, de la comptabilité ou des stocks. Même des erreurs d’arrondi mineures peuvent entraîner des problèmes importants. L'API BCMath Object améliorée de PHP 8.4 offre une solution raffinée pour des calculs décimaux précis et efficaces.
Les développeurs PHP expérimentés sont familiers avec l'imprécision en virgule flottante :
<code class="language-php">$a = 0.1; $b = 0.2; var_dump($a + $b); // Outputs: 0.30000000000000004</code>
Cette inexactitude est inacceptable dans des contextes financiers. Ces petites erreurs s'accumulent, conduisant à des écarts réels.
Les calculs décimaux précis commencent par la base de données. Le type DECIMAL
est indispensable :
<code class="language-php">// In Laravel Migration Schema::create('items', function (Blueprint $table) { $table->id(); $table->decimal('quantity', 10, 3); // Precision: 10 digits, 3 decimal places $table->decimal('price', 10, 3); // Precision: 10 digits, 3 decimal places $table->decimal('discount', 10, 3); // Precision: 10 digits, 3 decimal places $table->decimal('tax', 10, 3); // Precision: 10 digits, 3 decimal places // ... other columns });</code>
DECIMAL
assure :
Bien que potentiellement légèrement plus lent que FLOAT
, l'avantage en termes de précision l'emporte sur la différence de performances dans les systèmes critiques.
Laravel simplifie la gestion des décimales grâce à son système de conversion :
<code class="language-php">class Item extends Model { protected $casts = [ 'quantity' => 'decimal:3', 'price' => 'decimal:3', 'discount' => 'decimal:3', 'tax' => 'decimal:3', ]; }</code>
Rappelons cependant que le casting Laravel gère principalement :
Même avec des types de bases de données corrects et un casting Laravel, des erreurs de calcul peuvent survenir :
<code class="language-php">// Database values $item1 = Item::find(1); // price: "99.99" $item2 = Item::find(2); // price: "149.99" // Calculation without BCMath $subtotal = $item1->price + $item2->price; $tax = $subtotal * 0.05; // 5% tax var_dump($tax); // Outputs: float(12.499000000000002) instead of 12.499</code>
Cela se produit parce que PHP convertit implicitement les chaînes en nombres lors de l'arithmétique :
<code class="language-php">// String values from database $price1 = "99.99"; $price2 = "149.99"; echo gettype($price1); // string // Implicit conversion to float $total = $price1 + $price2; echo gettype($total); // double (float)</code>
L'extension BCMath traditionnelle apporte de la précision :
<code class="language-php">// Database values $item1 = Item::find(1); // price: "99.99" $item2 = Item::find(2); // price: "149.99" // Using BCMath functions $subtotal = bcadd($item1->price, $item2->price, 3); $tax = bcmul($subtotal, $item2->tax, 3); var_dump($tax); // Precisely outputs: string(5) "12.499"</code>
Cependant, les calculs complexes deviennent verbeux et moins maintenables :
<code class="language-php">// Complex order calculation (using BCMath functions) // ... (code omitted for brevity)</code>
L'API BCMath orientée objet de PHP 8.4 simplifie les calculs précis :
<code class="language-php">use BCMath\Number; $item1 = Item::find(1); $price = new Number($item1->price); $quantity = new Number($item1->quantity); $discountRate = new Number($item1->discount); $taxRate = new Number($item1->tax); // Natural and readable calculations $subtotal = $price * $quantity; $discount = $subtotal * $discountRate; $afterDiscount = $subtotal - $discount; $tax = $afterDiscount * $taxRate; $total = $afterDiscount + $tax; var_dump($total); // Automatically converts to string</code>
Avantages de la nouvelle API :
Stringable
implémentation de l'interface.Une élégance supplémentaire est obtenue avec les accessoires de Laravel :
<code class="language-php">use BCMath\Number; class Item extends Model { // ... (accessor methods for quantity, price, discount, tax using Number) ... }</code>
Ou avec un casting personnalisé :
<code class="language-php">// ... (DecimalCast class implementation) ...</code>
Puis :
<code class="language-php">$item1 = Item::find(1); $subtotal = $item1->price * $item1->quantity; // ... (rest of the calculation) ...</code>
Dans la gestion des stocks de soins de santé, des calculs décimaux précis sont essentiels. L'API BCMath Object de PHP 8.4, intégrée à Laravel, améliore considérablement la gestion de ces calculs, offrant précision, lisibilité, maintenabilité et sécurité des types. Alors que les anciennes fonctions BCMath ont rempli leur objectif, cette nouvelle approche rationalise considérablement le développement.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!