簡體   English   中英

比較浮點數的怪異結果

[英]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

有關如何正確比較浮點數的更多說明,請參見以下答案:

比較C中的浮點數

對於您的應用程序來說,這可能是過高的選擇,但是如果您不介意使用開源且穩定的庫,則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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM