Trong Java, “NaN” là viết tắt của “Không phải là số”. Nó không phải là một loại ngoại lệ, khá ngạc nhiên là kiểu dữ liệu của NaN cũng là một số. Nhưng thông thường, khi các lập trình viên mới làm quen vô tình sử dụng nó, họ sẽ tiếp tục sử dụng nó trong các tính toán của mình. Do đó, các kiểu dữ liệu không tương thích trong Java khi được sử dụng cùng nhau có thể gây ra lỗi có thể ném được. Nó cũng thường được java.lang.ArithmeticException: / by zerocoi là giống như NaN. Tuy nhiên, Java đối xử với cả hai khác nhau. Đủ khó hiểu? Để bạn hiểu toàn diện, chúng tôi sẽ phân tích xem chúng khác nhau như thế nào. Đến cuối bài viết này, bạn sẽ tìm hiểu về các thao tác có thể tạo ra số không (nan) và một số cách dễ dàng để xử lý nó.

NaN là gì?

Vậy NaN là gì? “NaN” như nhiều bạn đã đoán, được sử dụng để biểu thị “Không phải là số” trong Java. Nó là một giá trị dấu phẩy động đặc biệt để biểu thị lỗi tràn và lỗi. Nó được tạo khi một số dấu phẩy động được chia cho 0 hoặc nếu căn bậc hai của một số âm được tính. NaN trong Java - 1Ví dụ: hãy xem đoạn mã sau.

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	
    }
}
đầu ra

NaN                                                                                                                                           
NaN                                                                                                                                           
NaN
Trong đoạn mã trên, bạn có thể thấy rằng NaN được tạo ra nhờ 3 thao tác đơn giản:
  • Chia một float / doublesố không với số không.
  • Lấy căn dưới của một số âm (Math.sqrt(-x)). Trong toán học, lấy căn bậc hai của một số âm sẽ dẫn đến một số ảo . Trường hợp này được xử lý bằng cách trả về NaN trong Java.
  • Lấy mod của một số bằng 0, sẽ trả về phần còn lại sau khi chia một giá trị cho 0. Do đó, NaN được trả về.

NaN khác với Vô cực Tích cực và Tiêu cực như thế nào?

Theo thông số kỹ thuật của IEEE 754, có ba giá trị dấu phẩy động & dấu phẩy động đặc biệt để xử lý các trường hợp biên:
  • dương vô cùng
  • âm vô cực
  • NaN
Kết quả của việc chia một số dương cho 0 là dương vô cùng. Tương tự, kết quả vô cực âm là kết quả của việc chia một số âm cho số không. Xin lưu ý rằng tất cả các giá trị dấu phẩy động cũng được áp dụng cho kiểu dữ liệu double. Độ chính xác hạn chế của phao đôi khi không đủ. Tuy nhiên, chúng ta sẽ xem cách NaN hoạt động cho cả float và double trong phần sau.

Phương thức NaN() là gì?

isNaN()là một trong những phương thức cơ bản trong Java để kiểm tra xem nó có phải là giá trị NaN hay không. Như chúng ta đã thảo luận về ba trường hợp ở trên, đã đến lúc kiểm tra xem phương thức isNaN() phân biệt như thế nào giữa các giá trị +infinity , -infinity và 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());
  }
}
đầu ra

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

Làm cách nào để so sánh các giá trị NaN?

Mỗi giá trị NaN được coi là khác biệt. Điều này có nghĩa là, không một NaN nào bằng bất kỳ NaN nào khác. Theo nguyên tắc này, nếu bạn so sánh một giá trị này với một giá trị khác thì kết quả luôn là âm. Vì, NaN không có thứ tự, do đó, một phép so sánh số liên quan đến ngay cả một NaN duy nhất cũng trả về sai. Java cung cấp Float.NaN và Double.NaN cho các trường hằng trong cả hai lớp để thực hiện so sánh. Chúng ta có thể phân biệt những điều này trong hai trường hợp riêng biệt:
  • Đúng: Chỉ trong trường hợp Không bình đẳng (!=)
  • Sai: Đối với tất cả các toán hạng so sánh (==, <=, >=, <, >)
Đây là một ví dụ làm việc cho các bạn:

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
  }
}

Làm cách nào để tạo giá trị NaN?

Trước khi kết thúc, chúng ta hãy xem xét một số ví dụ phổ biến về việc nhận Không phải là Số (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));
  }
}
Đầu ra:

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

Phần kết luận

Sau khi xem xét nhiều hoạt động tạo ra NaN, bạn phải làm quen với nó ngay bây giờ. Ban đầu nó có thể khiến bạn bối rối, nhưng không có gì phức tạp khi giải quyết vấn đề này. Bằng cách phát triển một thói quen nhỏ kiểm tra xem một giá trị không phải là NaN trong các phép tính dấu chấm động/dấu chấm động có thể giúp bạn tránh khỏi rất nhiều rắc rối. Ngay cả khi bạn quên điều này ban đầu, nó hoàn toàn ổn. Bạn luôn có thể tham khảo bài viết này để khắc phục sự cố nhỏ. Tạo mã có thể biên dịch được, không có lỗi trong một lần sau nhiều năm kinh nghiệm. Vì vậy, hãy bắt tay vào viết mã và xây dựng thứ gì đó tuyệt vời!