2011-11-10 19 views
25

Powiel możliwe:
How to resolve a Java Rounding Double issueJak porównać dwie wartości podwójne w Javie?

Proste porównanie dwóch wartości podwójnych w Javie stwarza pewne problemy. Rozważmy następujący prosty fragment kodu w Javie.

package doublecomparision; 

final public class DoubleComparision 
{ 
    public static void main(String[] args) 
    { 
     double a = 1.000001; 
     double b = 0.000001; 

     System.out.println("\n"+((a-b)==1.0)); 
    } 
} 

Powyższy kod wydaje się powrót true, oceny ekspresji ((a-b)==1.0) ale tak nie jest. Zamiast tego zwracana jest wartość false, ponieważ ocena tego wyrażenia to 0.9999999999999999, co do którego oczekuje się, że będzie to 1.0, co nie jest równe 1.0, dlatego warunek jest wartością boolean false. Jaki jest najlepszy i sugerowany sposób na pokonanie takiej sytuacji?

+6

Dzieje się tak, ponieważ double i float nie mogą wyrażać każdej wartości liczbowej. Używają przybliżenia, aby przedstawić wartość. – onit

Odpowiedz

53

Zasadniczo nie należy robić dokładnych porównań, należy zrobić coś takiego:

double a = 1.000001; 
double b = 0.000001; 
double c = a-b; 
if (Math.abs(c-1.0) <= 0.000001) {...} 
+7

Możesz rzucić okiem na metodę porównania Double'a. Sprawdź ten link: http://www.tutorialspoint.com/java/lang/double_compare.htm –

+12

Ale jeśli użyjesz Double.compare, zauważ, że (1) Jeśli oba d1 i d2 reprezentują Double.NaN, to metoda zwraca true, nawet jeśli Double.NaN == Double.NaN ma wartość false; i (2) Jeśli d1 oznacza +0,0, podczas gdy d2 oznacza -0,0, lub odwrotnie, metoda zwraca wartość false, nawet jeśli +0,0 == - 0,0 ma wartość true. Ta definicja umożliwia poprawne działanie tabel mieszających. – shiggity

8

Zamiast używać podwójnych znaków dziesiętnych, użyj java.math.BigDecimal. Dałoby to oczekiwane rezultaty.

Dla porównania przyjrzeć się tej stackoverflow question

+14

BigDecimal czasami nie jest dobrym rozwiązaniem. – mcfinnigan

Powiązane problemy