我有以下代码(printfs用于调试)
float maximum = max(num1, max(num2, num3));
float other1 = min(num1, min(num2, num3));
float other2 = num1 + num2 + num3 - other1 - maximum;
//Now we know the maximum is maybe the hypothenuse
printf("Max %f, other %f, other %f\n", maximum, other1, other2);
printf("%f %f %f\n", pow(other1, 2), pow(other2, 2), pow(maximum, 2));
printf("%d\n", (pow(other1, 2) + pow(other2, 2)) == pow(maximum, 2));
return(pow(other1, 2) + pow(other2, 2) == pow(maximum, 2));
我要做的是检查3个号码是否是毕达哥拉斯三重奏。好吧,当输入数字3,4和5时,它返回0.
我不知道为什么会出现这种情况。我很确定问题在于比较,但我没有得到什么问题......
我会感激一些帮助!谢谢!
答案 0 :(得分:2)
假设你的数学是正确的,问题在于浮动比较。因为花车和双打不会产生"确切的"结果,只需使用" =="比较不起作用。
相反,你需要做类似的事情:
// if the difference between the two is very small they are basically equivalent
if fabs(a - b) < 0.00001
有关如何正确比较浮动的更多解释,请参阅此答案:
答案 1 :(得分:1)
这可能对你的应用程序来说太过分了,但是如果你不介意使用开源和稳定的库,那么GSL有一个名为int gsl_fcmp (double x, double y, double epsilon)
的函数,它将两个双精度浮点数与任何所需的epsilon进行比较(精度) 。这考虑了相对准确性,其算法比fabs()
更强大。它也非常适合测试你的代码。
编译时安装gsl并链接到库。使用其他包含,添加
#include <gsl/gsl_math.h>
然后你的代码将是
float maximum = max(num1, max(num2, num3));
float other1 = min(num1, min(num2, num3));
float other2 = num1 + num2 + num3 - other1 - maximum;
//Now we know the maximum is maybe the hypothenuse
printf("Max %f, other %f, other %f\n", maximum, other1, other2);
printf("%f %f %f\n", pow(other1, 2), pow(other2, 2), pow(maximum, 2));
int is_comparable = (0 == gsl_fcmp (pow(other1, 2) + pow(other2, 2),
pow(maximum, 2), 0.00001));
printf("%d\n", is_comparable);
return is_comparable;
我应该补充一点,GSL代表GNU Scientific Library
答案 2 :(得分:-1)
引用Eric Postpischil对Why is my integer math with std::pow giving the wrong answer?的回答:
到目前为止,所有其他答案都错过或围绕问题中的唯一问题:C ++实现中的
pow
质量很差。如果不需要,它会返回一个不准确的答案。获得更好的C ++实现,或者至少替换其中的数学函数。
另请参阅Pascal Cuoq对std::pow with integer parameters, comparing to an integer type和http://blog.frama-c.com/index.php?post/2013/04/06/Non-experts-need-accurate-floating-point-the-most的回答。