Jak sprawdzasz, czy podwójne jest równe NaN?

283

Mam podwójne w Javie i chcę sprawdzić, czy tak jest NaN. Jak najlepiej to zrobić?

Eric Wilson
źródło

Odpowiedzi:

475

Użyj statycznej Double.isNaN(double)metody, albo zwrot Double„s .isNaN()metody.

// 1. static method
if (Double.isNaN(doubleValue)) {
    ...
}
// 2. object's method
if (doubleObject.isNaN()) {
    ...
}

Po prostu robiąc:

if (var == Double.NaN) {
    ...
}

nie jest wystarczający ze względu na sposób zdefiniowania standardu IEEE dla liczb NaN i liczb zmiennoprzecinkowych .

Ben S.
źródło
51
Innym sposobem na to byłoby v! = V. Tylko NaN porównuje fałsz ze sobą. Nie rób tego jednak, isNaN jest milion razy lepszy. :)
Joren
5
@Joren, lepiej późno niż wcale: 'isNaN' jest rzeczywiście lepiej używać niż v! = V dla czytelności. Ale kod źródłowy metody isNaN jest dokładnie taki sam, jak powiedzenie v! = V. Źródło: statyczny publiczny boolean isNaN (podwójne v) {return (v! = V); }
Rolf ツ
1
Double.isNaN should be (true) niezła odpowiedź
Oliver Shaw,
@Joren toNaN po prostu sprawdź v! = V;), ale wygląda lepiej
Pan Jedi
Korzystanie z Java 5: value == Double.NaNnie działa, ale Double.isNaN(value)działa dobrze.
zero01alpha
45

Spróbuj Double.isNaN():

Zwraca true, jeśli ta podwójna wartość jest liczbą inną niż Na (NaN), w przeciwnym razie false.

Zauważ, że [ double.isNaN()] nie będzie działać, ponieważ do dublowanych rozpakowanych nie są powiązane z nimi metody.

Andrew Hare
źródło
Myślałem, że nie można wywoływać metod na prymitywnych typach w Javie. To naprawdę musi być Double.isNan()i nie double.IsNan(), prawda?
Joren
Joren, opiera się na autoboxingu (podwójne kompilowanie / kompilacja w środowisko uruchomieniowe); nowa funkcja od 1.5. Niewielkie ryzyko pójścia w tym kierunku; przejście z Double na Double stwarza ryzyko NullPointerExceptions.
M1EK,
Myślałem, że autoboxing działa tylko na wykorzystaniu podwójnego argumentu, dodaniu go do kolekcji i tym podobnych. Spróbuj zadeklarować podwójne x, a następnie poprosić x o isNaN () - daje mi błąd kompilatora.
Carl
Naprawdę podejrzewam, że Andrew właśnie przegapił klawisz Shift, wpisując pierwsze „podwójne”.
Carl
14

Możesz również rozważyć sprawdzenie, czy wartość jest skończona przez Double.isFinite(value). Od wersji Java 8 istnieje nowa metoda w Doubleklasie, w której można od razu sprawdzić, czy wartość nie jest NaN i nieskończoność.

/**
 * Returns {@code true} if the argument is a finite floating-point
 * value; returns {@code false} otherwise (for NaN and infinity
 * arguments).
 *
 * @param d the {@code double} value to be tested
 * @return {@code true} if the argument is a finite
 * floating-point value, {@code false} otherwise.
 * @since 1.8
 */
public static boolean isFinite(double d)
Grzegorz Gajos
źródło
10

Możesz sprawdzić NaN za pomocą var != var. NaNnie jest równy NaN.

EDYCJA : To prawdopodobnie zdecydowanie najgorsza metoda. Jest to mylące, okropne dla czytelności i ogólnie złe praktyki.

HyperNeutrino
źródło
3
Czy ktoś może wyjaśnić opinię negatywną? Wiem, że ten sposób jest bardzo zły i isNanpoprawia czytelność, ale działa, prawda? A isNanmetoda wykorzystuje to do sprawdzenia NaN.
HyperNeutrino,
1
Zgaduję, że głos był negatywny, ponieważ ten sposób jest bardzo zły, a isNaN jest lepszy dla czytelności.
Edward Falk
1
Nie głosowałem za tobą, ale myślę, że przydałby się dodatkowy komentarz: jeśli porównasz opakowania takie jak Float lub Double, w ten sposób porównasz referencje w ten sposób, a nie ich wartości, co zdecydowanie nie jest tym, czego chcesz.
Battle_Slug
3
@Battle_Slug Dzięki za komentarz. Wiem, że to bardzo zły pomysł, ale umieszczam go tutaj dla kompletności.
HyperNeutrino
isNaNrobi to pod maską, ale jak to działa? Jak coś się nie równa?
wilmol
0

Początkujący potrzebują praktycznych przykładów. więc wypróbuj następujący kod.

public class Not_a_Number {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    String message = "0.0/0.0 is NaN.\nsimilarly Math.sqrt(-1) is NaN.";        
    String dottedLine = "------------------------------------------------";     

    Double numerator = -2.0;
    Double denominator = -2.0;      
    while (denominator <= 1) {
        Double x = numerator/denominator;           
        Double y = new Double (x);
        boolean z = y.isNaN();
        System.out.println("y =  " + y);
        System.out.println("z =  " + z);
        if (z == true){
            System.out.println(message);                
        }
        else {
            System.out.println("Hi, everyone"); 
        }
        numerator = numerator + 1;
        denominator = denominator +1;
        System.out.println(dottedLine);         
    } // end of while

} // end of main

} // end of class
pggajendra babu
źródło
2
Ten przykład robi za dużo i nie jest jasne, co próbujesz pokazać. To tylko garść pofragmentowanego kodu.
Jared Hooper,
3
Jako OP, który był początkujący, kiedy pytanie zadano w 2009 roku, mogę was zapewnić, że zaakceptowana odpowiedź była o wiele bardziej pomocna niż byłby ten „praktyczny” przykład.
Eric Wilson
Dziękujemy @pggajendra babu za opublikowanie tego przykładowego kodu.
datnt
0

Poniższy fragment kodu pomoże ocenić typ pierwotny zawierający NaN.

double dbl = Double.NaN; Double.valueOf(dbl).isNaN() ? true : false;

Teela
źródło