2009-10-07 8 views
6

Właśnie przeczytałem oświadczenie o porównania wartość zmiennoprzecinkowąPorównując wartości zmiennoprzecinkowych

wartości zmiennoprzecinkowe nie powinny być porównywane za pomocą albo == lub! = operatorów. Większość wartości zmiennoprzecinkowych nie ma dokładnej reprezentacji binarnej i ma ograniczoną precyzję .

Jeśli tak, to jaka jest najlepsza metoda porównywania dwóch wartości zmiennoprzecinkowych?

+0

Czy możesz wyjaśnić, dlaczego musisz je porównać? A może jesteś ciekawy tej dokumentacji? – rjmunro

+0

możliwy duplikat [Jak wykonać porównanie zmiennoprzecinkowe?] (Http://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison) – Magnus

Odpowiedz

7

następujące metody przedłużające mogą być przydatne do realizacji Kevina sugestia:

public static bool IsEqualTo(this double a, double b, double margin) 
{ 
    return Math.Abs(a - b) < margin; 
} 

public static bool IsEqualTo(this double a, double b) 
{ 
    return Math.Abs(a - b) < double.Epsilon; 
} 

Więc teraz można po prostu zrobić:

if(x1.IsEqualTo(x2)) ... 
if(x1.IsEqualTo(x2, 0.01)) ... 

Wystarczy zmienić IsEqualTo do bardziej odpowiedniej nazwy, lub zmienić domyślny margines na wszystko, co jest lepsze niż double.Epsilon, w razie potrzeby.

3

Ogólnie liczb zmiennoprzecinkowych należy porównywać za pomocą konstruktu jak

if(abs((x1 - x2) < 0.001)) 

powodem ostrzeżenia cytowany jest może masz dwie metody obliczania coś, i mogą one być równe, jeśli nie miał zaokrąglania błąd , ale błąd zaokrąglenia powoduje, że są nieco inne.

+1

użyj 'abs (x1 - x2) <0.001 * x1' zamiast –

+0

@Alexandre: dlaczego? Byłoby pomocne, gdybyś mógł dać nam jakieś wyjaśnienie. – shuhalo

+1

@ user411768: dzieje się tak z powodu "ogólnie". Generalnie porównujesz względną precyzję, a nie bezwzględność. Co jeśli x1 i x2 są rzędu 10^-6, ale x1 jest pięć razy większy od x2? Na pewno nie chcesz, aby powyższy konstrukt powiedział ci, że x1 == x2. Są jednak przypadki, w których absolutna precyzja jest właściwa. Temat jest trudny. –

2

"Najlepsza metoda" zależy od okoliczności, dla których chcesz porównać liczby. Ogólnie rzecz biorąc, jeśli myślisz, że chcesz sprawdzić, czy 2 numery zmiennoprzecinkowe są równe, robisz coś nie tak.

Liczby zmiennoprzecinkowe mają służyć do reprezentowania rzeczywistych wartości w obu znaczeniach tego słowa. Czy ten obiekt jest tej samej długości co ten inny obiekt? Cóż, mogą wyglądać na taką samą długość, ale jeśli masz wystarczająco dobre urządzenie pomiarowe, zawsze możesz znaleźć różnicę. Podobnie, dwie liczby zmiennoprzecinkowe nigdy nie są równe, chyba że mierzą to samo i zostały przetworzone w dokładnie taki sam sposób. Poza tym jest to błąd zaokrągleń gdzieś w systemie.

Możesz chcieć sprawdzić, czy są blisko (bliżej niż określony próg), co sugerowały inne odpowiedzi, ale nie są one równe.

Powiązane problemy