在 Java 中,“NaN”代表“不是數字”。這不是一種異常類型,令人驚訝的是,NaN 的數據類型也是一個數字。但往往當新手程序員無意中得到它時,他們會在計算中進一步使用它。因此,Java 中不兼容的數據類型一起使用時會導致可拋出的錯誤。通常也可以看到它
java.lang.ArithmeticException: / by zero
被認為與 NaN 相同。然而,Java 以不同的方式對待它們。夠令人費解嗎?為了您的全面理解,我們將剖析它們之間的區別。到本文結束時,您將了解可能產生非數字 (nan) 的操作,以及一些處理它的簡單方法。
什麼是南?
那麼,NaN 是什麼?許多人已經猜到“NaN”在 Java 中用來表示“非數字”。它是一個特殊的浮點值,用於表示溢出和錯誤。當浮點數除以零或計算負數的平方根時生成。例如,看看下面的片段。
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
}
}
輸出
NaN
NaN
NaN
在上面的代碼片段中,您可以觀察到 NaN 是 3 個簡單操作的結果:
- 零除以
float / double
零。 - 取負數的根 (Math.sqrt(-x))。在數學中,對負數求平方根會得到一個虛數。這種情況通過在 Java 中返回 NaN 來處理。
- 用零取模,將返回一個值除以零後的餘數。因此,返回 NaN。
NaN 與正無窮大和負無窮大有何不同?
根據 IEEE 754 規範,有三種特殊的浮點和雙精度值來處理邊界情況:- 正無窮大
- 負無窮大
- 鈉鹽
什麼是 NaN() 方法?
isNaN()
是 Java 中檢查它是否為 NaN 值的基本方法之一。正如我們上面討論的三種情況,是時候測試 isNaN() 方法如何區分+infinity、-infinity和 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());
}
}
輸出
+Infinity.IsNaN() = false
-Infinity.IsNaN() = false
NaN.IsNaN() = true
如何比較 NaN 值?
每個 NaN 值都被認為是不同的。這意味著,沒有一個 NaN 等於任何其他 NaN。根據這一原則,如果將一個值與另一個值進行比較,結果總是負數。由於 NaN 是無序的,因此即使涉及單個 NaN 的數字比較也會返回 false。Java 為這兩個類中的常量字段都提供了 Float.NaN 和 Double.NaN 來進行比較。我們可以在兩個不同的場景中區分它們:- True:僅在不相等的情況下 (!=)
- False:對於所有比較操作數(==、<=、>=、<、>)
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
}
}
如何生成 NaN 值?
在結束之前,讓我們看一下獲取非數字 (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));
}
}
輸出:
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