C语言中基于Epsilon规则判断直角三角形的代码问题排查
问题
我写了一段C语言代码,想在不使用sqrt()或abs()函数的前提下,通过判断三边平方差的绝对值是否小于Epsilon(0.05)来判定一个三角形是否为直角三角形,但代码只在部分测试用例中有效。请问哪里出错了?
代码如下:
int IsRightTriangle(float side1, float side2, float side3) { if (side3*side3-(side1*side1+side2*side2) <= 0.05 || side3*side3-(side1*side1+side2*side2) >= -0.05) { return 1; } else if (side1*side1-(side3*side3+side2*side2) <= 0.05 || side1*side1-(side3*side3+side2*side2) >= -0.05) { return 1; } else if (side2*side2-(side3*side3+side1*side1) <= 0.05 || side2*side2-(side3*side3+side1*side1) >= -0.05) { return 1; } else return 0; }
测试结果:
Running test: IsRightTriangle(edge1=15.00, edge2=27.00, edge3=29.55) -- Passed Running test: IsRightTriangle(edge1=21.02, edge2=19.00, edge3=9.00) -- Failed
问题分析与修正
你的核心错误是逻辑运算符用反了:你想用<=0.05 && >=-0.05来判断数值的绝对值是否在允许范围内,但写成了||(逻辑或)。任何实数都满足“小于等于0.05 或者 大于等于-0.05”,这导致你的代码几乎总是返回1,只有当平方差超出这个区间时才会返回0——完全不符合需求。
另外,代码存在重复计算,还可以加入三角形合法性检查让逻辑更严谨。修正后的代码如下:
int IsRightTriangle(float side1, float side2, float side3) { // 先验证是否能构成三角形(可选,避免无效输入干扰判断) if (side1 + side2 <= side3 || side1 + side3 <= side2 || side2 + side3 <= side1) { return 0; } float diff1 = side3*side3 - (side1*side1 + side2*side2); float diff2 = side1*side1 - (side3*side3 + side2*side2); float diff3 = side2*side2 - (side3*side3 + side1*side1); // 用&&判断数值是否落在[-0.05, 0.05]区间内 if ((diff1 <= 0.05 && diff1 >= -0.05) || (diff2 <= 0.05 && diff2 >= -0.05) || (diff3 <= 0.05 && diff3 >= -0.05)) { return 1; } else { return 0; } }
关键修改点:
- 将每个判断条件中的
||替换为&&,正确实现“绝对值小于等于0.05”的判断 - 把重复计算的平方差存入变量,提升代码可读性和执行效率
- 增加三角形合法性检查,避免非三角形的输入干扰判断
内容的提问来源于stack exchange,提问作者Omer Rudnick
相关产品推荐
相关产品推荐

