功能特性
- 支持整數/小數、正/負數
- 可選四捨五入或截斷小數
- 可選小數進位到元
- 可選整數尾零附加「零」字(如 1960.30 → 壹仟玖佰陸拾元零三角)
- 自定義貨幣單位(元/圓)
完整類代碼
<?php
class Num2Rmb {
public static function convert(
string $number = '0',
string $intUnit = '元',
bool $round = true,
bool $extraZero = false,
bool $decToInt = false
): string {
// 分割整數/小數部分
$parts = explode('.', $number, 2);
$int = isset($parts[0]) ? $parts[0] : '0';
$dec = isset($parts[1]) ? $parts[1] : '';
// 小數處理:超過 2 位
if (strlen($dec) > 2) {
if ($round) {
$rounded = round((float)"0.$dec", 2);
if ($rounded == 1.0 && $decToInt) { // 進位到元
$int = (string)((int)$int + 1);
$dec = '00';
} elseif ($rounded == 1.0) { // 不進位,置為 0.99
$dec = '99';
} else {
$dec = substr((string)$rounded, 2); // 取小數點後兩位
}
} else {
$dec = substr($dec, 0, 2); // 直接截斷
}
}
// 零值特判
if ($int === '0' && ($dec === '' || $dec === '00' || $dec === '0')) {
return '零';
}
// 中文數字與單位映射
$chs = ['零','壹','貳','參','肆','伍','陸','柒','捌','玖'];
$uni = ['','拾','佰','仟'];
$decUni = ['角','分'];
$exp = ['','萬']; // 億級動態擴展
// 整數部分:從右向左,每 4 位一段
$res = '';
for ($i = strlen($int) - 1, $k = 0; $i >= 0; $k++) {
$seg = '';
for ($j = 0; $j < 4 && $i >= 0; $j++, $i--) {
$digit = (int)$int[$i];
$u = $digit > 0 ? $uni[$j] : '';
$seg = $chs[$digit] . $u . $seg;
}
$seg = rtrim($seg, '零');
$seg = preg_replace('/零+/', '零', $seg); // 合併連續零
if (!isset($exp[$k])) $exp[$k] = $exp[$k - 2] . '億';
$u2 = $seg !== '' ? $exp[$k] : '';
$res = $seg . $u2 . $res;
}
// 小數部分
$dec = rtrim($dec, '0');
if ($dec !== '') {
$res .= $intUnit;
if ($extraZero && substr($int, -1) === '0') $res .= '零';
for ($i = 0, $cnt = strlen($dec); $i < $cnt; $i++) {
$digit = (int)$dec[$i];
$u = $digit > 0 ? $decUni[$i] : '';
$res .= $chs[$digit] . $u;
}
$res = rtrim($res, '零');
$res = preg_replace('/零+/', '零', $res);
} else {
$res .= $intUnit . '整';
}
return ($number[0] === '-') ? '(負)' . $res : $res;
}
}
// 使用示例
echo Num2Rmb::convert('1600020039.9989', '圓', false, false, false);
// 輸出:壹拾陸億零貳萬零參拾玖圓玖角玖分
參數說明表
| 參數 | 類型 | 默認 | 說明 |
| $number | string | '0' | 數字字符串,避免浮點精度丟失 |
| $intUnit | string | '元' | 貨幣單位,財務常用「圓」 |
| $round | bool | true | 小數超 2 位是否四捨五入 |
| $extraZero | bool | false | 整數尾零且有小數時是否加「零」 |
| $decToInt | bool | false | 小數進位到元(如 0.995→1 元) |
測試用例
// 基礎
echo Num2Rmb::convert('123.45'); // 壹佰貳拾叁元肆角伍分
echo Num2Rmb::convert('1000'); // 壹仟元整
echo Num2Rmb::convert('1000.00'); // 壹仟元整
echo Num2Rmb::convert('1000.01'); // 壹仟元零壹分
echo Num2Rmb::convert('1960.30', '元', true, true); // 壹仟玖佰陸拾元零三角
echo Num2Rmb::convert('0.01'); // 零元壹分
echo Num2Rmb::convert('-500.50'); // (負)伍佰元伍角
echo Num2Rmb::convert('999.999', '元', true, false, true); // 壹仟元整(進位)