ב-Java, "NaN" מייצג "לא מספר". זה לא סוג של חריג, באופן מפתיע, גם סוג הנתונים של NaN הוא מספר. אבל לעתים קרובות כאשר מתכנתים מתחילים מקבלים את זה בלי כוונה, הם עוד משתמשים בזה בחישובים שלהם. מכאן שסוגי נתונים לא תואמים ב-Java בשימוש יחד עלולים לגרום לשגיאה שניתן לזרוק. זה גם נפוץ לראות שנחשב
לדוגמה, עיין בקטע הבא.
java.lang.ArithmeticException: / by zero
זהה ל-NaN. עם זאת, Java מתייחסת לשניהם בצורה שונה. מספיק תמוה? להבנתך המקיפה, ננתח כיצד אלה שונים זה מזה. בסוף מאמר זה תלמדו על הפעולות האפשריות שמפיקות לא מספר (nan), וכמה דרכים קלות לטפל בזה.
מה זה NaN?
אז מה זה NaN? "NaN" כפי שרבים מכם ניחשו, משמש לייצוג "Not a Number" ב-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)). במתמטיקה, לקיחת השורש הריבועי של מספר שלילי מביא למספר דמיוני . מקרה זה מטופל על ידי החזרת NaN ב-Java.
- נטילת מוד של מספר עם אפס, תחזיר את השארית לאחר חלוקת ערך באפס. לפיכך, NaN מוחזר.
במה שונה NaN מאינסוף חיובי ושלילי?
על פי מפרט IEEE 754, ישנם שלושה ערכים מיוחדים של נקודה צפה וערכים כפולים לטיפול במקרי הגבול:- אינסוף חיובי
- אינסוף שלילי
- NaN
מהי שיטת 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 בודד מחזירה שקר. Java מספקת Float.NaN ו-Double.NaN עבור שדות קבועים בשתי המחלקות לביצוע השוואות. אנו יכולים להבדיל בין אלה בשני תרחישים נפרדים:- נכון: רק במקרה של חוסר שוויון (!=)
- שקר: עבור כל אופרנדים להשוואה (==, <=, >=, <, >)
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?
לפני סיום, הבה נסתכל על כמה דוגמאות נפוצות לקבלת ה-Not a Number (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