mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-12-06 09:09:10 +08:00
Compare commits
6 Commits
9b1c8c35e4
...
d4510bfeb1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4510bfeb1 | ||
|
|
9c71cd27f2 | ||
|
|
1ee9e0759c | ||
|
|
0db075d34f | ||
|
|
715ac57494 | ||
|
|
c1cdf23e17 |
@ -1,9 +1,13 @@
|
||||
|
||||
# 🚀Changelog
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.43
|
||||
# 5.8.43(2025-12-01)
|
||||
|
||||
### 🐣新特性
|
||||
* 【core 】 `ColorUtil`颜色名称DARKGOLD、LIGHTGOLD新增蛇形命名匹配(pr#1400@Github)
|
||||
### 🐞Bug修复
|
||||
* 【core 】 修复`Calculator.conversion(String expression)`方法计算包含科学计数法表达式的值时逻辑有误,结果不符合预期(pr#4172@Github)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
# 5.8.42(2025-11-28)
|
||||
|
||||
|
||||
@ -99,10 +99,10 @@ public class ColorUtil {
|
||||
return Color.CYAN;
|
||||
} else if ("BLUE".equals(colorName)) {
|
||||
return Color.BLUE;
|
||||
} else if ("DARKGOLD".equals(colorName)) {
|
||||
} else if ("DARKGOLD".equals(colorName) || "DARK_GOLD".equals(colorName)) {
|
||||
// 暗金色
|
||||
return hexToColor("#9e7e67");
|
||||
} else if ("LIGHTGOLD".equals(colorName)) {
|
||||
} else if ("LIGHTGOLD".equals(colorName) || "LIGHT_GOLD".equals(colorName)) {
|
||||
// 亮金色
|
||||
return hexToColor("#ac9c85");
|
||||
} else if (StrUtil.startWith(colorName, '#')) {
|
||||
@ -117,7 +117,7 @@ public class ColorUtil {
|
||||
final Integer r = Convert.toInt(rgb.get(0));
|
||||
final Integer g = Convert.toInt(rgb.get(1));
|
||||
final Integer b = Convert.toInt(rgb.get(2));
|
||||
if (false == ArrayUtil.hasNull(r, g, b)) {
|
||||
if (!ArrayUtil.hasNull(r, g, b)) {
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -174,35 +174,90 @@ public class Calculator {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将表达式中负数的符号更改
|
||||
*
|
||||
* @param expression 例如-2+-1*(-3E-2)-(-1) 被转为 ~2+~1*(~3E~2)-(~1)
|
||||
* @return 转换后的字符串
|
||||
* 将表达式中的一元负号转换为内部标记(~),便于后续解析。
|
||||
* 规则说明:
|
||||
* - 科学计数法整体识别为数字,e/E 后的 + 或 - 属于指数符号,不参与一元符号折叠。
|
||||
* - 一元 + / - 仅在表达式开头或运算符、左括号之后生效;可折叠连续符号,如 --3、+-3 -> ~3。
|
||||
* 示例:
|
||||
* - 输入:-2+-1*(-3E-2)-(-1)
|
||||
* - 输出:~2+~1*(~3E~2)-(~1)
|
||||
*/
|
||||
private static String transform(String expression) {
|
||||
expression = StrUtil.cleanBlank(expression);
|
||||
expression = StrUtil.removeSuffix(expression, "=");
|
||||
final char[] arr = expression.toCharArray();
|
||||
|
||||
final StringBuilder out = new StringBuilder(arr.length);
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
if (arr[i] == '-') {
|
||||
if (i == 0) {
|
||||
arr[i] = '~';
|
||||
} else {
|
||||
char c = arr[i - 1];
|
||||
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
|
||||
arr[i] = '~';
|
||||
char c = arr[i];
|
||||
|
||||
// 把x或X当作 *
|
||||
if (CharUtil.equals(c, 'x', true)) {
|
||||
out.append('*');
|
||||
continue;
|
||||
}
|
||||
|
||||
// 若是'+'或'-',需要判断是指数符号、二元运算符还是一元运算符序列
|
||||
if (c == '+' || c == '-') {
|
||||
// 如果前一个已写入的字符为'e'或'E',则视作科学计数法的符号
|
||||
int outLen = out.length();
|
||||
if (outLen > 0) {
|
||||
char prevOut = out.charAt(outLen - 1);
|
||||
if (prevOut == 'e' || prevOut == 'E') {
|
||||
// 在e/E 后:
|
||||
// '+' 可以安全丢弃(1e+3 == 1e3)
|
||||
// '-' 必须保留但不能被当作二元运算符,故用'~'临时替代,后续再还原为'-'
|
||||
if (c == '-') {
|
||||
out.append('~');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if(CharUtil.equals(arr[i], 'x', true)){
|
||||
// issue#3787 x转换为*
|
||||
arr[i] = '*';
|
||||
|
||||
// 查找前一个非空字符(原串中的),用于判断是否为一元上下文
|
||||
int j = i - 1;
|
||||
while (j >= 0 && Character.isWhitespace(arr[j])) j--;
|
||||
boolean unaryContext = (j < 0) || isPrevCharOperatorOrLeftParen(arr[j]);
|
||||
|
||||
if (unaryContext) {
|
||||
// 收集连续的一系列 + 或 -(例如 --+ - -> 合并为一个净符号)
|
||||
int k = i;
|
||||
int minusCount = 0;
|
||||
while (k < arr.length && (arr[k] == '+' || arr[k] == '-')) {
|
||||
if (arr[k] == '-') minusCount++;
|
||||
k++;
|
||||
}
|
||||
boolean netNegative = (minusCount % 2 == 1);
|
||||
if (netNegative) {
|
||||
// 用~标记一元负号(与原实现保持兼容)
|
||||
out.append('~');
|
||||
}
|
||||
i = k - 1;
|
||||
} else {
|
||||
//二元运算符,直接写入 + 或 -
|
||||
out.append(c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//其它字符(包括数字、字母、括号、e、E、小数点等)直接追加
|
||||
out.append(c);
|
||||
}
|
||||
if (arr[0] == '~' && (arr.length > 1 && arr[1] == '(')) {
|
||||
arr[0] = '-';
|
||||
return "0" + new String(arr);
|
||||
|
||||
// 特殊处理:如果开头为 "~(",原实现会将其转为 "0~(" 形式改为以0开始的负括号处理
|
||||
final String result = out.toString();
|
||||
final char[] resArr = result.toCharArray();
|
||||
if (resArr.length >= 2 && resArr[0] == '~' && resArr[1] == '(') {
|
||||
resArr[0] = '-';
|
||||
return "0" + new String(resArr);
|
||||
} else {
|
||||
return new String(arr);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断给定位置前一个非空字符是否为运算符或左括号(用于判定是否为一元上下文)
|
||||
*/
|
||||
private static boolean isPrevCharOperatorOrLeftParen(char c) {
|
||||
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(';
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,4 +66,34 @@ public class CalculatorTest {
|
||||
result = calculator1.calculate("0+50/100X(1/0.5)");
|
||||
assertEquals(1D, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scientificNotationPlusTest() {
|
||||
// 测试科学记数法中的 + 号是否被正确处理
|
||||
final double conversion = Calculator.conversion("1e+3");
|
||||
assertEquals(1000.0, conversion, 0.001);
|
||||
|
||||
// 更复杂的科学记数法表达式
|
||||
final double conversion2 = Calculator.conversion("2.5e+2 + 1.0e-1");
|
||||
assertEquals(250.1, conversion2, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unaryOperatorConsistencyTest() {
|
||||
// 测试连续的一元运算符:双重负号--3,等同于 -( -3 ) = 3
|
||||
final double conversion = Calculator.conversion("--3");
|
||||
assertEquals(3.0, conversion, 0.001);
|
||||
|
||||
// 测试连续的一元运算符:正号后跟负号,等同于 +( -3 ) = -3
|
||||
final double conversion2 = Calculator.conversion("+-3");
|
||||
assertEquals(-3.0, conversion2, 0.001);
|
||||
|
||||
// 测试表达式开始的一元+运算符
|
||||
final double conversion3 = Calculator.conversion("+3");
|
||||
assertEquals(3.0, conversion3, 0.001);
|
||||
|
||||
// 测试表达式开始的一元-运算符
|
||||
final double conversion4 = Calculator.conversion("-3");
|
||||
assertEquals(-3.0, conversion4, 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user