Java质数判断函数无法通过单元测试,CRC32校验结果不符
质数判断方法的错误分析与修正
你的isPrime方法存在三个关键错误,导致遍历0-9999999时CRC32校验不匹配:
1. 误将1判定为质数
当n=1时,1%2 !=0会进入后续逻辑,而Math.sqrt(1)=1.0,循环条件i<=sqrt(3<=1.0)不成立,最终返回true,但1并不是质数。
2. 错误排除了唯一的偶质数2
2是质数,但原方法中2%2==0会直接返回false,完全忽略了这个特殊情况。
3. double类型平方根的精度风险
Math.sqrt返回的double类型对大整数可能存在精度丢失,比如某些大的完全平方数,其平方根的double值会略小于实际整数,导致循环提前终止,漏判该数为非质数。
修正后的代码
public static boolean isPrime(int n) { // 小于2的数都不是质数 if (n <= 1) { return false; } // 单独处理唯一的偶质数2 if (n == 2) { return true; } // 排除其他所有偶数 if (n % 2 == 0) { return false; } // 转为整数平方根,避免double精度问题 int sqrt = (int) Math.sqrt(n); // 只遍历奇数,步长设为2提升效率 for (int i = 3; i <= sqrt; i += 2) { if (n % i == 0) { return false; } } return true; }
修正说明
- 新增
n<=1的判断,直接返回false,修正1的误判; - 单独处理
n=2,确保这个唯一的偶质数被正确识别; - 将平方根转为
int类型,避免double精度丢失导致的循环终止条件错误; - 循环步长改为2,只遍历奇数,既减少循环次数提升效率,又避免重复检查偶数因子;
- 移除不必要的
boolean变量f,发现因子直接返回false,简化逻辑。
用修正后的方法执行单元测试,CRC32校验值会匹配预期的783904569L。
内容的提问来源于stack exchange,提问作者Snowbird2001
相关产品推荐
相关产品推荐

