将普通的计算公式转换为高精度计算,可以处理括号的情况
```<?php
namespace fast;
class Math
{
// 定义高精度四则运算公式计算函数
public static function precedence($operator)
{
switch ($operator) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
default:
return 0;
}
}
// 将计算公式转换为逆波兰表达式
public static function convertToReversePolish($expression)
{
$output = []; // 输出队列
$stack = []; // 运算符栈
$expression = str_replace(' ', '', $expression); // 移除空格
$operators = ['+', '-', '*', '/', '^']; // 运算符集合
$i = 0;
while ($i < strlen($expression)) {
$token = $expression[$i];
if (is_numeric($token)) {
// 如果是数字,直接加入输出队列
$number = '';
while ($i < strlen($expression) && (is_numeric($expression[$i]) || $expression[$i] == '.')) {
$number .= $expression[$i];
$i++;
}
$output[] = $number;
} elseif (in_array($token, $operators)) {
// 如果是运算符
while (!empty($stack) && in_array(end($stack), $operators) && self::precedence(end($stack)) >= self::precedence($token)) {
// 从栈中将优先级高于或等于当前运算符的运算符弹出,并加入输出队列
$output[] = array_pop($stack);
}
$stack[] = $token; // 当前运算符入栈
$i++;
} elseif (
$token == '('
) {
// 如果是左括号,入栈
$stack[] = $token;
$i++;
} elseif (
$token == ')'
) {
// 如果是右括号,将栈中的运算符弹出并加入输出队列,直到遇到左括号
while (!empty($stack) && end($stack) != '(') {
$output[] = array_pop($stack);
}
if (!empty($stack) && end($stack) == '(') {
array_pop($stack);
}
$i++;
} else {
// 存在无法识别的字符
return "Invalid character";
}
}
// 将栈中剩余的运算符加入输出队列
while (!empty($stack)) {
if (end($stack) == '(') {
return "Mismatched parentheses";
}
$output[] = array_pop($stack);
}
return $output;
}
// 高精度计算逆波兰表达式
public static function calculateReversePolishNotation($expression)
{
$stack = [];
// 遍历逆波兰表达式中的每个元素
foreach ($expression as $token) {
if (is_numeric($token)) {
// 如果是数字,则将其压入栈中
$stack[] = $token;
} else {
// 如果是运算符,则弹出栈顶两个数字进行计算,并将结果压入栈中
$operand2 = array_pop($stack);
$operand1 = array_pop($stack);
switch ($token) {
case '+':
$result = bcadd($operand1, $operand2, 2);
break;
case '-':
$result = bcsub($operand1, $operand2, 2);
break;
case '*':
$result = bcmul($operand1, $operand2, 2);
break;
case '/':
$result = bcdiv($operand1, $operand2, 2);
break;
default:
return "Invalid operator";
}
$stack[] = $result;
}
}
// 返回栈顶元素作为最终结果
return end($stack);
}
// 过滤浮点型数据小数点后面多余的0
public static function filterDecimal($number)
{
$filteredNumber = rtrim($number, '0');
if ($filteredNumber[strlen($filteredNumber) - 1] == '.') {
$filteredNumber = rtrim($filteredNumber, '.');
}
return $filteredNumber;
}
//高精度计算计算
public static function calcu($expression)
{
$res = self::calculateReversePolishNotation(self::convertToReversePolish($expression));
return $res;
}
}