Android计算器解析器处理负数时触发NumberFormatException问题求助
Android计算器解析器负数处理修复方案
问题根源
原解析器核心问题是无法区分一元负号(表示负数)和二元减号(减法运算):
- 输入
-5+5时,直接用运算符分割会得到["", "5", "5"],空字符串调用toFloat()触发NumberFormatException。 getDelimiter方法逻辑错误,遇到+返回空字符串,且无法正确识别表达式中的有效二元运算符。
修复方案
以下是修改后的完整代码,重点调整字符串分割逻辑、运算符识别逻辑,保留原有计算逻辑:
class CalculatorParser(private var expression: String) { init { if (expression.isEmpty() || expression == "0") { expression = "0+0" } else if (!expression.contains(Regex("[+\\-*/^]"))) { // 仅当表达式无任何运算符时,才追加+0 expression = "$expression+0" } } // 使用正则分割:区分一元负号和二元运算符 private val splitStr: MutableList<String> = run { // 正则规则:在+/*^后分割,或在非运算符位置前遇到-时不分割(保留负数) val regex = Regex("(?<=[+*/^])|(?=-)(?![+*/^])") val parts = expression.split(regex).filter { it.isNotEmpty() }.toMutableList() // 处理开头就是负数的情况,确保分割后有至少两个元素 if (parts.size == 1) { parts.add("0") } parts } private val a = splitStr[0].toFloat() private val b = splitStr[1].toFloat() private val operator = getDelimiter(expression) private fun getDelimiter(str: String): String { // 优先匹配二元运算符,排除开头的一元负号 return when { str.contains("+") -> "+" str.substring(1).contains("-") -> "-" // 从索引1开始检查,跳过开头的负号 str.contains("*") -> "*" str.contains("^") -> "^" str.contains("/") -> "/" else -> "+" } } private fun calculate(): Float { return when (operator) { "+" -> a + b "-" -> a - b "*" -> a * b "/" -> a / b "^" -> pow(a.toInt(), b.toInt()).toFloat() else -> 0f } } fun eval(result: Float = calculate()): String { return if (result.toString().contains(".")) { val splitResult = result.toString().split(".") if (splitResult[1].toInt() > 0) { result.toString() } else { result.toInt().toString() } } else { result.toString() } } private fun pow(base: Int, power: Int): Int { var result = base var i = 1 while (i < power) { result *= base i++ } return result } }
关键修改说明
- 正则分割逻辑:使用
(?<=[+*/^])|(?=-)(?![+*/^])正则表达式,确保仅在二元运算符后分割,保留负数的一元负号。 - 运算符识别优化:
getDelimiter从索引1开始检查-,避免把开头的负号误判为减法运算符。 - 初始化逻辑调整:用正则判断表达式是否含运算符,替代原有的split长度判断,准确性更高。
测试验证
输入-5+5时:
splitStr结果为["-5", "5"]- 识别运算符为
+ - 计算结果
-5 + 5 = 0,符合预期
内容的提问来源于stack exchange,提问作者user19606960
相关产品推荐
相关产品推荐

