C语言testIfPrime()函数误判奇数为素数,求问题原因及解决方法
修复C语言素数判断函数的错误
你的核心问题和你猜测的完全一致:for循环里的else分支在第一次判断(iIterate=3)时,只要余数不为0就直接break并判定为素数,根本没检查后续的因数。比如25,25%3≠0就直接输出素数,但实际上25能被5整除,这就导致所有大于2的奇数都被误判为素数。另外代码还存在一个隐藏错误:把唯一的偶素数2判定成了非素数。
修复后的代码
#include <math.h> #include <stdio.h> void testIfPrime(double lfNumber1) { int iNumber = (int)floor(lfNumber1); // 小于2的数都不是素数 if (iNumber < 2) { printf("\n%d is not a prime number.\n", iNumber); return; } // 单独处理唯一的偶素数2 if (iNumber == 2) { printf("\n%d is a prime number.\n", iNumber); return; } // 其他偶数直接判定为非素数 if (iNumber % 2 == 0) { printf("\n%d is not a prime number.\n", iNumber); return; } // 只遍历奇数因数,循环到sqrt(iNumber)即可(优化效率) for (int iIterate = 3; iIterate <= sqrt(iNumber); iIterate += 2) { if (iNumber % iIterate == 0) { printf("\n%d is not a prime number.\n", iNumber); return; } } // 循环结束未找到因数,说明是素数 printf("\n%d is a prime number.\n", iNumber); }
关键修改说明
- 拆分逻辑判断:把小于2的数、2、其他偶数分开处理,避免原代码的逻辑漏洞。
- 移除循环内的else分支:只有找到能整除的因数时,才输出非素数并终止函数;如果循环正常结束,说明没有任何因数,此时才判定为素数。
- 优化循环效率:
- 只遍历奇数(
iIterate += 2),跳过偶数因数(已经提前排除了偶数)。 - 循环终止条件改为
iIterate <= sqrt(iNumber),因为如果一个数有大于其平方根的因数,必然对应一个小于平方根的因数,无需遍历到iNumber-1。
- 只遍历奇数(
测试1-100的数字时,这个版本能正确区分素数和非素数,比如9、15、25这类奇数合数会被正确判定为非素数,2会被判定为素数。
内容的提问来源于stack exchange,提问作者J. Bowen
相关产品推荐
相关产品推荐

