十六进制计算器减法、除法运算异常问题修复方案咨询
问题根因分析
1. 减法崩溃问题
- 核心原因:当
num1 < num2时,num1 - num2结果为负数,Integer.toHexString()处理负数会返回对应32位补码的无符号十六进制字符串(比如-21会返回fffffff5),再调用Integer.parseInt()解析该字符串时,值超出了有符号int的正数范围,直接抛出NumberFormatException导致崩溃 - 冗余问题:现有代码存在多次无意义的类型转换:运算结果转十六进制串→转int→再转十六进制串,完全可以省略中间步骤
2. 除法无小数问题
- 核心原因:使用int类型做除法运算,int为整数类型,运算时会自动截断小数部分,自然无法输出小数结果,需要改用浮点类型运算,单独实现整数、小数部分的十六进制转换逻辑
修复后代码
private void hexa_calc() { try { // 读取输入的十六进制数转成long,避免int溢出问题 long num1 = Long.parseLong(e_one.getText().toString().trim(), 16); long num2 = Long.parseLong(e_two.getText().toString().trim(), 16); String result = ""; if (appKey1.operation.equals("+")) { long res = num1 + num2; result = Long.toHexString(res); } else if (appKey1.operation.equals("-")) { long res = num1 - num2; // 负数单独处理符号,避免补码问题 if (res < 0) { result = "-" + Long.toHexString(-res); } else { result = Long.toHexString(res); } } else if (appKey1.operation.equals("X")) { long res = num1 * num2; result = Long.toHexString(res); } else if (appKey1.operation.equals("/")) { if (num2 == 0) { t_result.setText("除数不能为0"); return; } // 处理整数部分 long integerPart = num1 / num2; // 处理小数部分,默认保留4位十六进制小数,可调整循环次数修改精度 double decimalPart = (double) (num1 % num2) / num2; StringBuilder decimalHex = new StringBuilder(); for (int i = 0; i < 4; i++) { decimalPart *= 16; int digit = (int) decimalPart; decimalHex.append(Integer.toHexString(digit)); decimalPart -= digit; if (decimalPart == 0) break; } // 拼接结果 if (decimalHex.length() > 0) { result = Long.toHexString(integerPart) + "." + decimalHex; } else { result = Long.toHexString(integerPart); } } // 输出结果,可根据需求转为大写 t_result.setText(result.toLowerCase()); } catch (NumberFormatException e) { t_result.setText("输入格式错误"); } }
关键修改说明
- 替换int为long类型运算,降低数值溢出概率
- 减法运算单独处理负数符号,直接对绝对值转十六进制后拼接负号,避免补码解析异常
- 除法运算拆分整数和小数部分分别转换,默认保留4位十六进制小数,可根据需求调整循环次数修改精度
- 新增异常捕获逻辑,避免输入非法值、除数为0等场景崩溃
内容的提问来源于stack exchange,提问作者M.alsaoud
相关产品推荐
相关产品推荐

