# StrToBcmath
**Repository Path**: crazy-dream/StrToBcmath
## Basic Information
- **Project Name**: StrToBcmath
- **Description**: StrToBcmath 是一个 PHP 类,旨在将字符串表达式转换为 BcMath 计算结果。它支持复杂的运算,包括加、减、乘、除和指数,能够处理括号优先级,能够兼容连续'-'、连续'+'、混合'+-'连续等情况。
- **Primary Language**: PHP
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 0
- **Created**: 2023-12-29
- **Last Updated**: 2025-08-05
## Categories & Tags
**Categories**: utils
**Tags**: Bcmath, 精度, PHP, km
## README
# StrToBcmath
## 介绍
**StrToBcmath** 是一个 PHP 类,旨在将字符串表达式转换为 BcMath 计算结果。它支持复杂的运算,包括加、减、乘、除和指数,能够处理括号优先级,能够兼容连续'-'、连续'+'、混合'+-'连续等情况。
## 为什么选择这个库?
当需要进行高精度计算时,BcMath 是理想的解决方案,它有效避免了小数计算带来的误差。然而,BcMath 的语法相对复杂,使用起来不够直观。**StrToBcmath** 通过支持易读的字符串表达式,使得数学运算更简单、清晰。
使用 **StrToBcmath** 的优势包括:
- **简洁性**:通过易读的表达式,减少代码复杂性。
- **高精度**:确保计算结果的准确性,特别适合财务和科学应用。
- **灵活性**:支持复杂运算,包括括号优先级和多种运算符。
无论是在日常开发还是复杂计算中,**StrToBcmath** 都能帮助你更高效地完成任务。
## 安装说明
1. **手动安装**:将 `StrToBcmath.php` 文件复制到你的项目中,并在需要的地方引入:
```php
require_once 'StrToBcmath.php';
```
2. **通过 Composer 安装**:
使用以下命令安装库:`composer require k6xiao/strtobcmath`
然后在代码中引入该库:
```php
use k6xiao\StrToBcmath;
```
## 使用说明
1. 创建一个 StrToBcmath 对象,设置精度和是否输出计算过程(可选):
```php
// @param $scale // 可选,精度,默认值:8
// @param $isecho // 可选,是否输出计算过程,默认值:false
$math = new StrToBcmath();
```
2. 使用 **of()** 方法计算表达式的结果:
```php
$result = bcdiv(bcadd(bcpow(bcadd(bcsub('2.5', '3.5'), '8'), '4'), '6'), '2');
// 可以写为
$result = $math->of('(((2.5-3.5)+8)**(5-1)+6)/2');
echo $result; // 输出: 1203.50000000
```
## 示例
以下是使用 **StrToBcmath** 的一些示例:
### 示例 1:计算手续费
```php
use k6xiao\StrToBcmath;
$money = 123.456;
$sxf = 0.6;
$fee = (new StrToBcmath(6))->of("$money * $sxf / 100");
echo "$money 的 $sxf% 手续费是:$fee"; // 输出: 123.456 的 0.6% 手续费是:0.740736
```
### 示例 2:重设精度和输出设置
```php
$math = new StrToBcmath();
$fee = $math->of("$money * $sxf / 100");
echo "$money 的 $sxf% 手续费是:$fee"; // 输出: 123.456 的 0.6% 手续费是:0.74073600
$fee = $math->of("$money * $sxf / 100", 4);
echo "$money 的 $sxf% 手续费是:$fee"; // 输出: 123.456 的 0.6% 手续费是:0.7407
$math->setScale(2); // 重设精度
$math->setIsecho(true); // 输出计算过程
$fee = $math->of("$money * $sxf / 100");
echo "$money 的 $sxf% 手续费是:$fee";
// 输出:
// 123.456*0.6/100
// =74.07/100
// =0.74
// 123.456 的 0.6% 手续费是:0.74
```
### 示例 3:计算多个表达式
```php
require_once 'StrToBcmath.php';
$expressions = [
'2*3+6+6/2',
'2/3',
'2+3',
'2-3',
'2-3**2',
'(5-3)**2',
'2.5*3.5',
'2.5/3.5',
'2.5+3.5',
'2.5-3.5',
'((2.5-3.5)+8)*3',
'(((2.5-3.5)+8)*(2.5-1)+6)/2',
];
// 计算并输出每个表达式的结果
foreach ($expressions as $expression) {
$result = (new StrToBcmath(6, true))->of($expression);
echo "$expression = $result
";
}
```
这将输出每个表达式的计算过程和结果:
```
2*3+6+6/2
=6.000000+6+6/2
=6.000000+6+3.000000
=12.000000+3.000000
=15.000000
2*3+6+6/2 = 15
2/3
=0.666666
2/3 = 0.666666
2+3
=5.000000
2+3 = 5
2-3
=-1.000000
2-3 = -1
2-3**2
=29.000000
2-3**2 = 29
(5-3)**2
=2.000000**2
=4.000000
(5-3)**2 = 4
2.5*3.5
=8.750000
2.5*3.5 = 8.75
2.5/3.5
=0.714285
2.5/3.5 = 0.714285
2.5+3.5
=6.000000
2.5+3.5 = 6
2.5-3.5
=-1.000000
2.5-3.5 = -1
((2.5-3.5)+8)*3
=(-1.000000+8)*3
=7.000000*3
=21.000000
((2.5-3.5)+8)*3 = 21
(((2.5-3.5)+8)*(2.5-1)+6)/2
=((-1.000000+8)*(2.5-1)+6)/2
=(7.000000*(2.5-1)+6)/2
=(7.000000*1.500000+6)/2
=16.500000/2
=8.250000
(((2.5-3.5)+8)*(2.5-1)+6)/2 = 8.25
```
### 示例 4:容错测试负数、多个'+-'号混合连续、小数指数运算
```php
require_once 'StrToBcmath.php';
$expressions = [
'---2---3',
'2+++---+++3',
'--2--3',
'3**-2.5',
'2--2**--3',
'2**+3',
'2*-3+6+6/2',
'2/-3',
'2+-3',
'-2--3',
'(5--3)**-2',
'-2.5*-3.5',
'-2.5/-3.5',
'-2.5+-3.5',
'2.5--3.5',
'((2.5--3.5)+-8)*-3',
'(((-2.5--3.5)+8)*(-2.5--1)+-6)/-2',
];
// 计算并输出每个表达式的结果
foreach ($expressions as $expression) {
$result = (new StrToBcmath(6, true))->of($expression);
echo "$expression = $result
";
}
```
这将输出每个表达式的计算过程和结果:
```
---2---3
=-+2-+3
=-2-3
=-5.000000
---2---3 = -5
2+++---+++3
=2+---+3
=2+---3
=2+-3
=-1.000000
2+++---+++3 = -1
--2--3
=+2--3
=+5.000000
--2--3 = 5
3**-2.5
=0.064150
3**-2.5 = 0.06415
2--2**--3
=2--2**+3
=4.000000**+3
2--2**--3 = 4
2**+3
=2**3
=8.000000
2**+3 = 8
2*-3+6+6/2
=-6.000000+6+6/2
=-6.000000+6+3.000000
=0.000000+3.000000
=3.000000
2*-3+6+6/2 = 3
2/-3
=-0.666666
2/-3 = -0.666666
2+-3
=-1.000000
2+-3 = -1
-2--3
=1.000000
-2--3 = 1
(5--3)**-2
=8.000000**-2
=0.015625
(5--3)**-2 = 0.015625
-2.5*-3.5
=8.750000
-2.5*-3.5 = 8.75
-2.5/-3.5
=0.714285
-2.5/-3.5 = 0.714285
-2.5+-3.5
=-6.000000
-2.5+-3.5 = -6
2.5--3.5
=6.000000
2.5--3.5 = 6
((2.5--3.5)+-8)*-3
=(6.000000+-8)*-3
=-2.000000*-3
=6.000000
((2.5--3.5)+-8)*-3 = 6
(((-2.5--3.5)+8)*(-2.5--1)+-6)/-2
=((1.000000+8)*(-2.5--1)+-6)/-2
=(9.000000*(-2.5--1)+-6)/-2
=(9.000000*-1.500000+-6)/-2
=-19.500000/-2
=9.750000
(((-2.5--3.5)+8)*(-2.5--1)+-6)/-2 = 9.75
```
## 注意
StrToBcmath 类使用 PHP 的 bcmath 库进行计算,所以你的 PHP 环境需要支持 bcmath 库。
## 项目源代码
你可以在以下地址找到我们的项目源代码:
- GitHub:[https://github.com/k6xiao/StrToBcmath.git](https://github.com/k6xiao/StrToBcmath.git)
- Gitee:[https://gitee.com/crazy-dream/StrToBcmath.git](https://gitee.com/crazy-dream/StrToBcmath.git)
- Composer:[https://packagist.org/packages/k6xiao/strtobcmath](https://packagist.org/packages/k6xiao/strtobcmath)
## 项目计划
1. 增加取余运算:`$num1 % $num2 ~~~ fmod(float $num1, float $num2)`
2. 建立讨论组,与有兴趣的伙伴一起维护、计划
3. 对于乘法表达式(\*):兼容‘x’号、省略‘\*’号的优化,比如允许`$math->of("$base $num·$price x $fee / 100")`等效于`$math->of("$base * $num * $price * $fee / 100")`。
## 更新记录
- [20250720] 兼容|BUG:支持负数的运算,解决负数计算 bug。
- [20250720] 兼容|BUG:兼容连续'-'、连续'+'、混合'+-'连续等情况。
- [20250720] 兼容支持小数指数的近似运算,使用 pow 函数处理小数指数。
- [20250720] 兼容:解决指数运算底与幂是小数、负数、多余'+'的情况。
- [20250805] 优化:增加maxScale传参,计算过程中使用最大精度计算(默认30位),保障最终结果更加准确。