<p>边界条件应设为 i ≤ sqrt(n) 或 i * i ≤ n,检查 2 到 √n(含)的整数能否整除 n;n ≤ 1 直接非质数,2 是最小质数。</p>

用 for 循环判断质数时,边界条件怎么设才不漏判也不多算
质数定义是大于 1 的正整数,且仅有 1 和它本身两个正因数。所以 2 是最小质数,1 不是,0 和负数直接排除。
循环只需检查从 2 到 sqrt(n)(含)之间的整数是否能整除 n——因为如果 n = a × b 且 a ≤ b,那么必有 a ≤ sqrt(n)。用 i * i 替代 <code>i 更安全,避免浮点误差和类型转换问题。
- 别写
for (int i = 2; i :对大数(比如 10⁶)效率极低 - 必须先特判
n → 返回 <code>false;n == 2→ 返回true - 偶数只需检查一次:
n > 2 && n % 2 == 0直接返回false,后续循环可只试奇数
为什么用 i * i
sqrt(n) 返回 double,强制转为 int 可能向下取整过头(如 sqrt(25) 理论是 5.0,但浮点计算可能得 4.999999,转 int 成 4,漏掉 i == 5 这一关键检查)。而 i * i 全是整数运算,无精度损失,且编译器通常能优化乘法成本。
- 当
n接近INT_MAX时,i * i可能溢出 → 改用i 更稳妥(整除向下取整,逻辑等价且无溢出) - 不要在循环条件里反复调用
sqrt(n):它不是常量表达式,每次迭代都算一遍,白费 CPU
完整可运行的判断函数长什么样
下面这个 is_prime 函数覆盖了常见坑点,支持 int 范围内输入:
bool is_prime(int n) {
if (n < 2) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
for (int i = 3; i <= n / i; i += 2) {
if (n % i == 0) return false;
}
return true;
}-
i += 2跳过所有偶数,省一半时间 i 是防溢出的推荐写法,比 <code>i * i 更健壮- 注意:
n / i是整数除法,当i > sqrt(n)时,n / i ,循环自然终止
实际用的时候,输入验证和性能要注意什么
如果你从用户或文件读入 n,别假设它一定合法。比如用 std::cin >> n 后,要检查 cin.fail(),否则非数字输入会让程序行为异常。另外,单次判断无所谓,但若需批量判断(如筛 10⁵ 个数),用埃氏筛或欧拉筛远快于反复调用 is_prime。
立即学习“C++免费学习笔记(深入)”;
- 对
n = 1、n = 0、n = -5,函数必须返回false,这是数学定义决定的 - 用
int存n时,最大安全值约 2×10⁹;再大就得上long long,此时循环上限也得改成i (<code>i * i更容易溢出) - 别为了“简洁”把逻辑全塞进一行:可读性和边界处理比少敲两个字符重要得多
真正卡住人的往往不是算法思路,而是 n == 2 忘特判、i 写成 <code>i 导致漏检平方数(如 <code>49),或者没意识到 1 不是质数。


















