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 zero
coi 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. Ví 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 / double
số 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
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 (==, <=, >=, <, >)
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
GO TO FULL VERSION