Heim >Backend-Entwicklung >PHP-Tutorial >Umgang mit Dezimalrechnungen in PHP mit der neuen BCMath-Objekt-API

Umgang mit Dezimalrechnungen in PHP mit der neuen BCMath-Objekt-API

Patricia Arquette
Patricia ArquetteOriginal
2025-01-23 12:04:11920Durchsuche

Handling Decimal Calculations in PHP  with the New BCMath Object API

Ursprünglich veröffentlicht im Blog von Takeshi Yu.


Genaue numerische Berechnungen sind in Unternehmensanwendungen von größter Bedeutung, insbesondere wenn es um Finanzen, Buchhaltung oder Inventar geht. Selbst geringfügige Rundungsfehler können zu erheblichen Problemen führen. Die verbesserte BCMath Object API von PHP 8.4 bietet eine verfeinerte Lösung für präzise und effiziente Dezimalberechnungen.


Erfahrene PHP-Entwickler sind mit der Ungenauigkeit von Gleitkommazahlen vertraut:

<code class="language-php">$a = 0.1;
$b = 0.2;
var_dump($a + $b);  // Outputs: 0.30000000000000004</code>

Diese Ungenauigkeit ist im finanziellen Kontext inakzeptabel. Diese kleinen Fehler häufen sich und führen zu Abweichungen in der realen Welt.

Datenbankdesign für Präzision

Präzise Dezimalrechnungen beginnen mit der Datenbank. Wesentlich ist der Typ DECIMAL:

<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 stellt sicher:

  • Exakte Dezimalgenauigkeit.
  • Anpassbare Skalierung und Präzision.
  • Eignung für Finanzanwendungen.

Obwohl möglicherweise etwas langsamer als FLOAT, überwiegt der Präzisionsvorteil den Leistungsunterschied in geschäftskritischen Systemen.

Laravels Casting nutzen

Laravel vereinfacht die Dezimalverarbeitung mit seinem Casting-System:

<code class="language-php">class Item extends Model
{
    protected $casts = [
        'quantity' => 'decimal:3',
        'price' => 'decimal:3',
        'discount' => 'decimal:3',
        'tax' => 'decimal:3',
    ];
}</code>

Denken Sie jedoch daran, dass das Laravel-Casting in erster Linie Folgendes schafft:

  • Datenformatierung.
  • Konsistente Wertdarstellung.

Fallstricke bei der Typkonvertierung vermeiden

Selbst bei korrekten Datenbanktypen und Laravel-Casting können Berechnungsfehler auftreten:

<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>

Dies geschieht, weil PHP während der Arithmetik implizit Zeichenfolgen in Zahlen umwandelt:

<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>

BCMath vor PHP 8.4: Präzise, ​​aber mühsam

Die traditionelle BCMath-Erweiterung bietet Präzision:

<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>

Komplexe Berechnungen werden jedoch ausführlicher und weniger wartbar:

<code class="language-php">// Complex order calculation (using BCMath functions)
// ... (code omitted for brevity)</code>

BCMath Object API von PHP 8.4: Eleganz und Präzision

Die objektorientierte BCMath-API von PHP 8.4 vereinfacht präzise Berechnungen:

<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>

Vorteile der neuen API:

  • Intuitives objektorientiertes Design.
  • Standardunterstützung für mathematische Operatoren.
  • Unveränderliche Objekte für Datenintegrität.
  • StringableSchnittstellenimplementierung.

Nahtlose Laravel-Integration

Weitere Eleganz wird mit den Accessoires von Laravel erreicht:

<code class="language-php">use BCMath\Number;

class Item extends Model
{
    // ... (accessor methods for quantity, price, discount, tax using Number) ...
}</code>

Oder mit einer individuellen Besetzung:

<code class="language-php">// ... (DecimalCast class implementation) ...</code>

Dann:

<code class="language-php">$item1 = Item::find(1);

$subtotal = $item1->price * $item1->quantity;
// ... (rest of the calculation) ...</code>

Fazit

Bei der Bestandsverwaltung im Gesundheitswesen sind präzise Dezimalberechnungen von entscheidender Bedeutung. Die in Laravel integrierte BCMath Object API von PHP 8.4 verbessert die Handhabung dieser Berechnungen erheblich und bietet Präzision, Lesbarkeit, Wartbarkeit und Typsicherheit. Während die älteren BCMath-Funktionen ihren Zweck erfüllten, rationalisiert dieser neue Ansatz die Entwicklung erheblich.

Das obige ist der detaillierte Inhalt vonUmgang mit Dezimalrechnungen in PHP mit der neuen BCMath-Objekt-API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Drupal AI-ModuleNächster Artikel:Drupal AI-Module