首頁 > 後端開發 > php教程 > 使用新的 BCMath 物件 API 在 PHP 中處理小數計算

使用新的 BCMath 物件 API 在 PHP 中處理小數計算

Patricia Arquette
發布: 2025-01-23 12:04:11
原創
919 人瀏覽過

Handling Decimal Calculations in PHP  with the New BCMath Object API

原發表於Takeshi Yu的部落格。


準確的數值計算在企業應用程式中至關重要,尤其是那些涉及財務、會計或庫存的應用程式。 即使很小的捨入誤差也會導致嚴重的問題。 PHP 8.4 增強的 BCMath 物件 API 為精確且有效率的小數計算提供了完善的解決方案。


經驗豐富的 PHP 開發人員熟悉浮點不精確性:

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

這種不準確在金融環境中是不可接受的。 這些小錯誤累積起來,就會導致現實世界的差異。

精確的資料庫設計

精確的小數計算從資料庫開始。 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 的 Cast

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>
登入後複製

PHP 8.4 之前的 BCMath:精確但乏味

傳統的 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:優雅與精確

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

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>
登入後複製

結論

在醫療保健庫存管理中,精確的小數計算至關重要。 PHP 8.4 的 BCMath 物件 API 與 Laravel 集成,顯著改進了這些計算的處理,提供精度、可讀性、可維護性和類型安全性。 雖然舊的 BCMath 函數達到了其目的,但這種新方法大大簡化了開發。

以上是使用新的 BCMath 物件 API 在 PHP 中處理小數計算的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板