CodeGym /Blog Java /rawak /NaN di Jawa
John Squirrels
Tahap
San Francisco

NaN di Jawa

Diterbitkan dalam kumpulan
Di Jawa, "NaN" bermaksud "Bukan Nombor". Ia bukan jenis pengecualian, agak mengejutkan, jenis data NaN juga merupakan nombor. Tetapi selalunya apabila pengaturcara pemula mendapatnya secara tidak sengaja, mereka terus menggunakannya dalam pengiraan mereka. Oleh itu, jenis data yang tidak serasi dalam Java apabila digunakan bersama boleh menyebabkan ralat boleh buang. Ia juga biasa dilihat yang java.lang.ArithmeticException: / by zerodianggap sama dengan NaN. Walau bagaimanapun, Java melayan mereka berdua secara berbeza. Cukup membingungkan? Untuk pemahaman menyeluruh anda, kami akan membedah bagaimana ini berbeza antara satu sama lain. Pada penghujung artikel ini, anda akan mempelajari tentang kemungkinan operasi yang menghasilkan bukan nombor (nan), dan beberapa cara mudah untuk mengendalikannya.

Apakah NaN?

Jadi, apakah itu NaN? "NaN" seperti yang anda sangka, digunakan untuk mewakili "Bukan Nombor" di Jawa. Ia ialah nilai titik terapung khas untuk menandakan limpahan dan ralat. Ia dijana apabila nombor titik terapung dibahagikan dengan sifar atau jika punca kuasa dua nombor negatif dikira. NaN dalam Java - 1Sebagai contoh, lihat coretan berikut.

public class NaN
{
    public static void main(String[]args)
    {
        System.out.println(0.0 / 0.0);	  //zero divided by zero
        System.out.println(Math.sqrt(-1)); //take sqrt of negative number
        System.out.println(10.0 % 0);      //taking mod by zero	
    }
}
Pengeluaran

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
Dalam coretan di atas, anda boleh melihat bahawa NaN dihasilkan hasil daripada 3 operasi mudah:
  • Membahagi float / doublesifar dengan sifar.
  • Mengambil di bawah punca nombor negatif (Math.sqrt(-x)). Dalam matematik, mengambil punca kuasa dua nombor negatif menghasilkan nombor khayalan . Kes ini ditangani dengan mengembalikan NaN di Jawa.
  • Mengambil mod nombor dengan sifar, akan mengembalikan baki selepas membahagikan nilai dengan sifar. Oleh itu, NaN dikembalikan.

Bagaimanakah NaN Berbeza daripada Infiniti Positif dan Negatif?

Menurut spesifikasi IEEE 754, terdapat tiga nilai titik terapung & berganda khas untuk mengendalikan kes sempadan:
  • Infiniti positif
  • Infiniti negatif
  • NaN
Hasil pembahagian nombor positif dengan 0 ialah infiniti positif. Begitu juga, hasil infiniti negatif hasil daripada membahagikan nombor negatif dengan sifar. Sila ambil perhatian bahawa semua nilai titik terapung juga boleh digunakan untuk jenis data berganda. Ketepatan terapung yang terhad kadangkala tidak mencukupi. Walau bagaimanapun, kita akan melihat cara NaN berfungsi untuk kedua-dua terapung dan berganda dalam bahagian kemudian.

Apakah KaedahNaN()?

isNaN()adalah salah satu kaedah asas dalam Java untuk menyemak sama ada ia adalah nilai NaN atau tidak. Seperti yang kita membincangkan tiga kes di atas, sudah tiba masanya untuk menguji bagaimana kaedah isNaN() membezakan antara nilai +infinity , -infinity dan NaN.

public class isNaN
{ public static void main(String[]args)
  { 
    Double posInfinity = +2.0 / 0.0;
    Double negInfinity = -3.5 / 0.0;
    Double nanVal = 50 % 0.0;


    System.out.println ("+" + posInfinity + ".IsNaN() = " + posInfinity.isNaN());
    System.out.println ( negInfinity + ".IsNaN() = " + negInfinity.isNaN());
    System.out.println ( nanVal +  ".IsNaN() = " + nanVal.isNaN());
  }
}
Pengeluaran

+Infinity.IsNaN() = false                                                                                                                       
-Infinity.IsNaN() = false                                                                                                                       
NaN.IsNaN() = true

Bagaimana untuk Membandingkan Nilai NaN?

Setiap nilai NaN dianggap berbeza. Ini bermakna, tiada satu NaN yang sama dengan mana-mana NaN lain. Dengan prinsip ini, Jika anda membandingkan satu nilai dengan yang lain hasilnya sentiasa negatif. Oleh kerana, NaN tidak tertib, jadi perbandingan berangka yang melibatkan walaupun satu NaN mengembalikan palsu. Java menyediakan Float.NaN dan Double.NaN untuk medan tetap dalam kedua-dua kelas untuk melakukan perbandingan. Kita boleh membezakannya dalam dua senario berasingan:
  • Benar: Hanya dalam kes In-equality (!=)
  • Salah: Untuk semua operan perbandingan (==, <=, >=, <, >)
Berikut ialah contoh yang berkesan untuk anda semua:

public class ComparingNaN
{ public static void main(String[] args)                                                                                                     
  {
    // Comparing NaN values for Float constants
    System.out.println (Float.NaN != Float.NaN); // true
    System.out.println (Float.NaN == Float.NaN); // false
    System.out.println (Float.NaN < Float.NaN);  // false
    System.out.println (Float.NaN > Float.NaN);  // false
    System.out.println (Float.NaN <= Float.NaN); // false
    System.out.println (Float.NaN >= Float.NaN); // false

    // Comparing NaN values for Float constants
    System.out.println (Double.NaN != Double.NaN); // true
    System.out.println (Double.NaN == Double.NaN); // false
    System.out.println (Double.NaN < Double.NaN);  // false
    System.out.println (Double.NaN > Double.NaN);  // false
    System.out.println (Double.NaN <= Double.NaN); // false
    System.out.println (Double.NaN >= Double.NaN); // false
  }
}

Bagaimana untuk Menjana Nilai NaN?

Sebelum mengakhiri, mari lihat beberapa contoh biasa untuk mendapatkan Bukan Nombor (nan).

public class GenerateNaNValues {  
  static final float ZERO = 0;
  public static void main (String[]args)
  {
    System.out.println("ZERO / ZERO = " + (ZERO / ZERO));
    System.out.println("+INFINITY - INFINITY = " + 
    (Float.POSITIVE_INFINITY + Float.NEGATIVE_INFINITY));
    System.out.println("-INFINITY * ZERO = " + (Float.NEGATIVE_INFINITY * ZERO));
    System.out.println("+INFINITY * ZERO = " + (Float.POSITIVE_INFINITY * ZERO));
    System.out.println("log10(-10) = " +  Math.log(-10));
    System.out.println("√-10 = " + Math.sqrt(-10));
    System.out.println("NaN + 10 = " + (Float.NaN + 10));
    System.out.println("NaN - 10 = " + (Float.NaN - 10));
    System.out.println("NaN * 10 = " + (Float.NaN * 10));
    System.out.println("NaN / 10 = " + (Float.NaN / 10));
    System.out.println("NaN + NaN = " + (Float.NaN + Float.NaN));
    System.out.println("NaN - NaN = " + (Float.NaN - Float.NaN));
    System.out.println("NaN * NaN = " + (Float.NaN * Float.NaN));
    System.out.println("NaN / NaN = " + (Float.NaN / Float.NaN));
  }
}
Pengeluaran:

ZERO / ZERO = NaN                                                                                                                               
+INFINITY - INFINITY = NaN                                                                                                                      
-INFINITY * ZERO = NaN                                                                                                                          
+INFINITY * ZERO = NaN                                                                                                                          
log10(-10) = NaN                                                                                                                                
√-10 = NaN                                                                                                                                      
NaN + 10 = NaN                                                                                                                                    
NaN - 10 = NaN                                                                                                                                  
NaN * 10 = NaN                                                                                                                                  
NaN / 10 = NaN                                                                                                                                  
NaN + NaN = NaN                                                                                                                                 
NaN - NaN = NaN                                                                                                                                 
NaN * NaN = NaN                                                                                                                                 
NaN / NaN = NaN

Kesimpulan

Selepas melihat banyak operasi yang menghasilkan NaN, anda pasti sudah biasa dengannya sekarang. Ia mungkin membingungkan anda pada mulanya, tetapi tidak ada yang rumit untuk menangani perkara ini. Dengan membangunkan sedikit tabiat menyemak sama ada nilai bukan NaN dalam pengiraan dua kali/titik terapung boleh menyelamatkan anda daripada banyak kerumitan. Walaupun anda terlupa ini pada mulanya, ia tidak mengapa. Anda sentiasa boleh merujuk artikel ini untuk menyelesaikan masalah kecil. Mencipta kod yang boleh dikompilasi, bebas ralat sekali gus datang selepas pengalaman bertahun-tahun. Jadi mari kita mengotorkan tangan kita dalam kod, dan membina sesuatu yang hebat!
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION