BCMath (Binary Calculator) 是 PHP 處理任意精度數學運算的標準擴展,廣泛應用於金融、電商、計費等對精度零容忍場景。本文整理所有 BCMath 函數的原型、參數說明、返回值與實戰代碼片段,作為開發查閱手冊。
| 函數 | 功能 | 簽名 | 關鍵參數 |
|---|---|---|---|
| bcadd | 加法 | string bcadd(string $left, string $right, int $scale=0) | $scale: 結果小數位數 |
| bcsub | 減法 | string bcsub(string $left, string $right, int $scale=0) | $scale: 結果小數位數 |
| bcmul | 乘法 | string bcmul(string $left, string $right, int $scale=0) | $scale: 結果小數位數 |
| bcdiv | 除法 | string bcdiv(string $left, string $right, int $scale=0) | $scale: 結果小數位數 (默認 0 即整除) |
| bcmod | 取模 | string bcmod(string $left, string $modulus) | 無 scale,整數運算 |
| bcpow | 冪運算 | string bcpow(string $left, string $right, int $scale=0) | $right 為指數,$scale 為結果小數位 |
| bcpowmod | 冪取模 | string bcpowmod(string $left, string $right, string $mod, int $scale=0) | 數論核心運算 (RSA 加密常用) |
| bcsqrt | 平方根 | string bcsqrt(string $operand, int $scale=0) | $scale: 結果小數位數 |
| bccomp | 比較 | int bccomp(string $left, string $right, int $scale=0) | 返回 -1/0/1,$scale 設定比較精度 |
| bcscale | 設定默認 scale | bool bcscale(int $scale) | 影響後續不指定 scale 的函數 |
<?php
$a = '4.45'; $b = '5.54';
if (bccomp($a, $b, 2) === 0) {
echo "相等";
} elseif (bccomp($a, $b, 2) < 0) {
echo "a < b";
} else {
echo "a > b";
}
?>
<?php $a = '1.0321456'; $b = '0.0123456'; $c = bcadd($a, $b, 2); // '1.04' ?>
<?php $a = '1.0321456'; $b = '3.0123456'; $c = bcsub($a, $b, 2); // '-1.98' ?>
<?php $a = '6'; $b = '4'; $c = bcmod($a, $b); // '2' ?>
<?php $a = '6'; $b = '5'; $c = bcdiv($a, $b, 3); // '1.200' (scale=3 保留3位) ?>
<?php $a = '3.1415926'; $b = '2.4569874566'; $c = bcmul($a, $b, 6); // '7.718...' ?>
<?php $a = '3.1415926'; $b = '2'; $c = bcpow($a, $b, 3); // '9.870' ?>
<?php $a = '2'; $b = bcsqrt($a, 6); // '1.414214' ?>
<?php
bcscale(4); // 後續 bcadd/bcsub... 不寫 scale 時默認 4 位
echo bcadd('1.1', '2.2'); // '3.3000'
?>
'1.23' 而非 1.23。- 符號,如 bcsub('1', '5', 2) → '-4.00'。'1.2E3' 會報錯,需預處理轉為普通十進制字符串。<?php
class Money {
private $amount; // string
private $currency;
const SCALE = 4;
public function __construct(string $amount, string $currency = 'CNY') {
$this->amount = $amount;
$this->currency = $currency;
}
public function add(Money $other): Money {
if ($this->currency !== $other->currency) throw new Exception('Currency mismatch');
return new Money(bcadd($this->amount, $other->amount, self::SCALE), $this->currency);
}
public function mul(string $factor): Money {
return new Money(bcmul($this->amount, $factor, self::SCALE), $this->currency);
}
public function format(int $displayScale = 2): string {
return bcadd($this->amount, '0', $displayScale); // 四捨五入格式化
}
}
?>
將 BCMath 封裝為領域模型,讓業務代碼遠離底層精度細節,是成熟系統的必經之路。