[英]Weird results comparing floats
我有以下代碼(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。
我不知道為什么會發生這種行為。 我很確定問題出在比較上,但我不明白這是怎么回事...
我將不勝感激! 謝謝!
假設您的數學是正確的,則問題是浮點比較。 由於浮點數和雙精度數不會產生“精確”結果,因此僅使用“ ==”比較不起作用。
相反,您需要執行以下操作:
// if the difference between the two is very small they are basically equivalent
if fabs(a - b) < 0.00001
有關如何正確比較浮點數的更多說明,請參見以下答案:
對於您的應用程序來說,這可能是過高的選擇,但是如果您不介意使用開源且穩定的庫,則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科學圖書館
引用Eric Postpischil的答案, 為什么我的std :: pow整數運算給出錯誤答案? :
所有其他的答案為止錯過或圍繞這一問題的唯一問題舞蹈-
pow
在C ++實現的質量不高。 不需要時會返回不正確的答案。獲得更好的C ++實現,或者至少替換其中的數學函數。
另請參閱Pascal Cuoq對帶有整數參數的std :: pow的答案, 與整數類型和http://blog.frama-c.com/index.php?post/2013/04/06/Non-experts-比較需要最准確的浮點數 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.