Merge pull request #4191 from qieugxi/hutool-1224-2

fix issue 4190
This commit is contained in:
Golden Looly
2025-12-27 13:18:31 +08:00
committed by GitHub
2 changed files with 44 additions and 2 deletions

View File

@@ -101,7 +101,8 @@ public class Calculator {
count++;
}
}
if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {// 最后一个字符不是括号或者其他运算符的则加入后缀式栈中
//新增防止数组越界
if (count > 1 || (count == 1 && currentIndex < arr.length && !isOperator(arr[currentIndex]))) {// 最后一个字符不是括号或者其他运算符的则加入后缀式栈中
postfixStack.push(new String(arr, currentIndex, count));
}
@@ -150,6 +151,14 @@ public class Calculator {
* @return 结果
*/
private BigDecimal calculate(String firstValue, String secondValue, char currentOp) {
final BigDecimal first = NumberUtil.toBigDecimal(firstValue);
final BigDecimal second = NumberUtil.toBigDecimal(secondValue);
//添加除零检查并提供明确错误信息
if ((currentOp == '/' || currentOp == '%') && second.compareTo(BigDecimal.ZERO) == 0) {
throw new ArithmeticException("Division by zero: cannot divide " + firstValue + " by zero");
}
final BigDecimal result;
switch (currentOp) {
case '+':
@@ -258,6 +267,6 @@ public class Calculator {
* 判断给定位置前一个非空字符是否为运算符或左括号(用于判定是否为一元上下文)
*/
private static boolean isPrevCharOperatorOrLeftParen(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(';
return c == '%' || c == '+' || c == '-' || c == '*' || c == '/' || c == '(';
}
}

View File

@@ -96,4 +96,37 @@ public class CalculatorTest {
final double conversion4 = Calculator.conversion("-3");
assertEquals(-3.0, conversion4, 0.001);
}
@Test
public void percentOperatorTest() {
//基础 % 运算
assertEquals(1.0, Calculator.conversion("10 % 3"), 0.001);
// % 运算符后跟连续的一元运算符的情况
assertEquals(1.0, Calculator.conversion("10 % +-3"), 0.001);
assertEquals(1.0, Calculator.conversion("10 % -3"), 0.001);
// 带括号的 % 后一元负号
assertEquals(1.0, Calculator.conversion("10 % (-3)"), 0.001);
// % 与 * / 的优先级测试
assertEquals(2.0, Calculator.conversion("10 * 5 % 3"), 0.001);
assertEquals(1.0, Calculator.conversion("20 / 5 % 3"), 0.001);
//连续 % 运算
assertEquals(2.0, Calculator.conversion("100 % 7 % 3"), 0.001);
// % 与 + - 混合运算
assertEquals(13.0, Calculator.conversion("10 + 15 % 4"), 0.001);
//负数操作数的 % 运算
assertEquals(-1.0, Calculator.conversion("-10 % 3"), 0.001);
// 两个负数的 % 运算
assertEquals(-1.0, Calculator.conversion("-10 % -3"), 0.001);
// 小数的 % 运算
assertEquals(0.9, Calculator.conversion("10.5 % 3.2"), 0.001);
}
}