Bagaimana Anda menguji untuk melihat apakah ganda sama dengan NaN?

283

Saya memiliki dobel di Jawa dan saya ingin memeriksa apakah ada NaN. Apa cara terbaik untuk melakukan ini?

Eric Wilson
sumber

Jawaban:

475

Gunakan statis Double.isNaN(double)metode, atau Anda Double's .isNaN()metode.

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

Cukup melakukan:

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

adalah tidak cukup karena bagaimana standar IEEE untuk NaN dan nomor floating point didefinisikan.

Ben S
sumber
51
Cara lain untuk melakukan ini adalah v! = V. Hanya NaN yang membandingkan false dengan dirinya sendiri. Tapi jangan lakukan itu, isNaN sejuta kali lebih baik. :)
Joren
5
@Joren, lebih baik terlambat daripada tidak pernah: 'isNaN' memang lebih baik untuk digunakan daripada v! = V untuk keterbacaan. Tetapi kode sumber metode isNaN persis sama dengan mengatakan v! = V. Sumber: static public boolean isNaN (double v) {return (v! = V); }
Rolf ツ
1
Double.isNaN should be (true) jawaban yang bagus
Oliver Shaw
@Joren isNaN hanya memeriksa v! = V;) tetapi terlihat lebih baik
Mr Jedi
Menggunakan Java 5: value == Double.NaNtidak berfungsi, tetapi Double.isNaN(value)berfungsi dengan baik.
zero01alpha
45

Coba Double.isNaN():

Mengembalikan nilai true jika nilai ganda ini adalah Not-a-Number (NaN), false jika tidak.

Perhatikan bahwa [ double.isNaN()] tidak akan berfungsi, karena dobel tanpa kotak tidak memiliki metode yang terkait dengannya.

Andrew Hare
sumber
Saya pikir Anda tidak dapat memanggil metode pada tipe primitif di Jawa. Itu benar-benar perlu Double.isNan()dan tidak double.IsNan(), bukan?
Joren
Joren, dia mengandalkan autoboxing (double dikonversikan menjadi Double oleh kompiler / runtime); fitur baru mulai 1,5 dan seterusnya. Sedikit risiko menuju ke arah ini; dari Double ke Double menciptakan risiko NullPointerExceptions.
M1EK
Saya pikir autoboxing hanya berfungsi menggunakan double sebagai argumen, menambahkannya ke koleksi, dan sejenisnya. Coba mendeklarasikan double x dan kemudian meminta x ke isNaN () - memberi saya kesalahan kompiler.
Carl
Sungguh, saya curiga Andrew hanya melewatkan tombol shift mengetik "ganda" pertama.
Carl
14

Anda mungkin ingin mempertimbangkan juga memeriksa apakah suatu nilai terbatas Double.isFinite(value). Karena Java 8 ada metode baru di Doublekelas di mana Anda dapat memeriksa sekaligus jika nilai bukan NaN dan tak terbatas.

/**
 * 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
sumber
10

Anda dapat memeriksa NaN dengan menggunakan var != var. NaNtidak sama NaN.

EDIT : Ini mungkin metode yang paling buruk. Ini membingungkan, mengerikan untuk dibaca, dan praktik buruk secara keseluruhan.

HyperNeutrino
sumber
3
Bisakah seseorang menjelaskan downvote? Saya tahu, cara ini sangat buruk, dan isNanlebih baik untuk dibaca, tetapi berfungsi, bukan? Dan isNanmetode ini menggunakan ini untuk memeriksa NaN.
HyperNeutrino
1
Saya menduga downvote itu karena cara ini sangat buruk, dan isNaN lebih baik untuk dibaca.
Edward Falk
1
Saya tidak menurunkan suara Anda, tetapi saya pikir komentar tambahan akan berguna di sini: jika Anda membandingkan pembungkus seperti Float atau Double Anda akhirnya membandingkan referensi dengan cara ini, bukan nilai-nilainya, yang jelas bukan yang Anda inginkan.
Battle_Slug
3
@Battle_Slug Terima kasih atas komentarnya. Saya tahu bahwa ini adalah ide yang sangat buruk, tetapi saya menaruhnya di sini untuk kelengkapan.
HyperNeutrino
isNaNapakah ini di bawah tenda, tetapi bagaimana cara kerjanya? Bagaimana sesuatu yang tidak sama dengan dirinya sendiri ??
wilmol
0

Pemula membutuhkan contoh-contoh praktis. jadi coba kode berikut.

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
sumber
2
Contoh ini terlalu banyak, dan tidak jelas apa yang Anda coba perlihatkan. Ini hanya sekelompok kode terfragmentasi.
Jared Hooper
3
Sebagai OP, yang adalah pemula ketika pertanyaan ini ditanyakan kembali pada '09, saya dapat meyakinkan Anda bahwa jawaban yang diterima jauh lebih bermanfaat daripada contoh "praktis" ini.
Eric Wilson
Terima kasih @pggajendra babu karena memposting kode contoh ini.
datnt
0

Cuplikan kode di bawah ini akan membantu mengevaluasi tipe primitif yang menahan NaN.

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

Teela
sumber