实现欧几里得算法约分分数时出现除零错误,求问题排查
问题分析与修复方案
导致除零错误的核心原因
- 未校验输入合法性:如果传入的分数分母(
a[1])为0,后续所有涉及分母的计算都会触发除零异常。 - 算法逻辑漏洞:原代码提前交换分子分母的大小,但如果交换前
a[1]为0,交换后a[0]会变成0,后续执行c/a[0]时直接触发除零错误。 - 符号处理不完整:仅处理了分子为负的情况,未考虑分母为负的场景,可能导致约分后符号不符合规范。
修复后的代码
public static long[] simp(long[] a) { // 拦截分母为0的非法输入 if (a[1] == 0) { throw new IllegalArgumentException("分母不能为0"); } long originalNum = a[0]; long originalDen = a[1]; // 统一符号:将负号转移到分子,分母保持为正 boolean isNegative = (originalNum < 0) ^ (originalDen < 0); long absNum = Math.abs(originalNum); long absDen = Math.abs(originalDen); // 欧几里得算法求最大公约数 long gcd = absNum; long temp = absDen; while (temp != 0) { long remainder = gcd % temp; gcd = temp; temp = remainder; } // 计算约分后的分子分母 long[] result = new long[2]; result[0] = isNegative ? -absNum / gcd : absNum / gcd; result[1] = absDen / gcd; System.out.println(result[0] + "/" + result[1]); return result; }
关键修改说明
- 输入合法性校验:新增分母为0的判断,直接抛出异常避免后续错误。
- 避免修改输入数组:单独保存原始分子分母,防止对输入参数造成副作用。
- 规范符号处理:通过异或运算判断分数整体符号,确保约分后分母始终为正,符合数学规范。
- 简化欧几里得算法:无需提前交换分子分母的大小,算法本身会自动处理大数模小数的情况,逻辑更简洁可靠。
内容的提问来源于stack exchange,提问作者Bryan Griffin
相关产品推荐
相关产品推荐

