ホームページ >バックエンド開発 >PHPチュートリアル >新しい BCMath オブジェクト API を使用した PHP での 10 進数計算の処理
元々は Takeshi Yu のブログで公開されました。
エンタープライズ アプリケーション、特に財務、会計、在庫を扱うアプリケーションでは、正確な数値計算が最も重要です。 わずかな丸め誤差であっても、重大な問題を引き起こす可能性があります。 PHP 8.4 の強化された BCMath オブジェクト API は、正確かつ効率的な 10 進数計算のための洗練されたソリューションを提供します。
経験豊富な PHP 開発者は、浮動小数点の不精度についてよく知っています。
<code class="language-php">$a = 0.1; $b = 0.2; var_dump($a + $b); // Outputs: 0.30000000000000004</code>
この不正確さは、金融の観点からは容認できません。 こうした小さな誤差が積み重なり、現実世界の不一致につながります。
正確な 10 進数の計算はデータベースから始まります。 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
は以下を保証します:
FLOAT
よりもわずかに遅い可能性がありますが、ミッションクリティカルなシステムでは精度の利点がパフォーマンスの違いを上回ります。
Laravel は、キャスト システムを使用して小数の処理を簡素化します。
<code class="language-php">class Item extends Model { protected $casts = [ 'quantity' => 'decimal:3', 'price' => 'decimal:3', 'discount' => 'decimal:3', 'tax' => 'decimal:3', ]; }</code>
ただし、Laravel のキャストは主に以下を管理することに注意してください。
正しいデータベースタイプと Laravel キャストを使用していても、計算エラーが発生する可能性があります:
<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>
これは、PHP が算術演算中に文字列を暗黙的に数値に変換するために発生します。
<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 拡張機能は精度を提供します。
<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>
ただし、複雑な計算は冗長になり、保守性が低くなります:
<code class="language-php">// Complex order calculation (using BCMath functions) // ... (code omitted for brevity)</code>
PHP 8.4 のオブジェクト指向 BCMath API により、正確な計算が簡素化されます。
<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>
新しい API の利点:
Stringable
インターフェースの実装。Laravel のアクセサーを使用すると、さらに優雅さが実現されます。
<code class="language-php">use BCMath\Number; class Item extends Model { // ... (accessor methods for quantity, price, discount, tax using Number) ... }</code>
またはカスタム キャストを使用する場合:
<code class="language-php">// ... (DecimalCast class implementation) ...</code>
その後:
<code class="language-php">$item1 = Item::find(1); $subtotal = $item1->price * $item1->quantity; // ... (rest of the calculation) ...</code>
ヘルスケアの在庫管理では、正確な小数計算が不可欠です。 Laravel と統合された PHP 8.4 の BCMath オブジェクト API は、これらの計算の処理を大幅に改善し、精度、可読性、保守性、型安全性を提供します。 古い BCMath 関数はその目的を果たしましたが、この新しいアプローチにより開発が大幅に合理化されます。
以上が新しい BCMath オブジェクト API を使用した PHP での 10 進数計算の処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。