You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sqrt函数返回值强制转换为整数导致的程序异常问题

完全平方数判断失效及循环异常问题排查

问题代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main() {

    double a, b, c;

    for (a = 1; a < 333; a++) {
        for (c = 335; c < 998; c++) {
            if ((sqrt(a) != (int) sqrt(a)) || (sqrt(c) != (int) sqrt(c))) continue;
            b = 1000 - c - a;
            if ((c * c) == (a * a) + (b * b)) break;
        }
    }

    printf("%.0lf + %.0lf + %.0lf = 1000\nProduct: %.0lf\n", a, b, c, a * b * c);

    system("pause");
    return 0;
}

问题描述

这段代码意图寻找满足a+b+c=1000且c²=a²+b²的勾股数,同时要求a和c是完全平方数,但运行后得到的a、c是循环的最大值,且完全平方数的判断逻辑失效——比如a=332时,sqrt(a)被错误识别为整数,实际计算值应为18.248288,却被当成18.0处理。

问题根源

  1. 浮点数精度丢失:用double类型存储整数a、c,循环中a++、c++的浮点数递增会导致精度误差。当数值较大时,double无法精确表示所有整数,比如332可能被存储为接近但略小的数值,导致sqrt(a)的计算结果出现偏差,后续与强制转换后的int值比较时误判为相等。
  2. 错误的完全平方数判断逻辑:直接用sqrt(a) != (int)sqrt(a)的方式判断,依赖浮点数的精确相等比较,而浮点数运算本身存在精度误差,很容易出现误判。
  3. 循环未正确终止:即使找到符合条件的数,内层循环break后外层循环仍会继续执行,最终覆盖为循环的最大值。

修复方案

  1. 将a、b、c改为int类型,彻底避免浮点数精度问题;
  2. 用整数运算实现完全平方数判断:计算k = sqrt(x)后,验证k*k == x(注意k需为整数);
  3. 找到符合条件的数后,同时终止内外层循环。

修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// 判断是否为完全平方数
int isPerfectSquare(int x) {
    if (x < 0) return 0;
    int k = (int)sqrt(x);
    return k * k == x;
}

int main() {
    int a, b, c;
    int found = 0; // 标记是否找到结果

    for (a = 1; a < 333; a++) {
        if (!isPerfectSquare(a)) continue; // 先判断a,减少内层循环次数
        for (c = 335; c < 998; c++) {
            if (!isPerfectSquare(c)) continue;
            b = 1000 - c - a;
            // 确保b是正整数,且满足勾股定理
            if (b > 0 && c*c == a*a + b*b) {
                found = 1;
                break;
            }
        }
        if (found) break; // 找到结果后终止外层循环
    }

    if (found) {
        printf("%d + %d + %d = 1000\nProduct: %lld\n", a, b, c, (long long)a*b*c);
    } else {
        printf("No valid solution found.\n");
    }

    system("pause");
    return 0;
}

说明

  • 新增isPerfectSquare函数,用整数运算验证完全平方数,避免浮点数误差;
  • 提前判断a是否为完全平方数,减少不必要的内层循环;
  • 加入found标记,找到结果后立即终止所有循环;
  • 输出乘积时用long long类型,避免整数溢出。

内容的提问来源于stack exchange,提问作者idk.mp3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:42:47