في جافا، يشير "NaN" إلى "ليس رقمًا". إنه ليس نوعًا من الاستثناء، بل من المدهش أن نوع بيانات NaN هو أيضًا رقم. ولكن في كثير من الأحيان عندما يحصل المبرمجون المبتدئون على هذه المعلومة عن غير قصد، فإنهم يستخدمونها أيضًا في حساباتهم. ومن ثم، فإن أنواع البيانات غير المتوافقة في Java عند استخدامها معًا يمكن أن تتسبب في حدوث خطأ يمكن التخلص منه. ومن الشائع أيضًا أن
java.lang.ArithmeticException: / by zero
يعتبر نفس NaN. ومع ذلك، تتعامل Java معهما بشكل مختلف. محير بما فيه الكفاية؟ من أجل فهمك الشامل، سنقوم بتحليل كيفية اختلاف هذه العناصر عن بعضها البعض. في نهاية هذه المقالة ستتعرف على العمليات الممكنة التي لا تنتج رقمًا (نان)، وبعض الطرق السهلة للتعامل معها.
ما هو نان؟
إذًا، ما هو 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 يتم إنتاجه نتيجة لثلاث عمليات بسيطة:
- قسمة
float / double
الصفر على صفر. - أخذ جذر الرقم السالب (Math.sqrt(-x)). في الرياضيات، يؤدي أخذ الجذر التربيعي لعدد سالب إلى الحصول على عدد وهمي . يتم التعامل مع هذه الحالة عن طريق إرجاع NaN في Java.
- سيؤدي أخذ تعديل رقم بصفر إلى إرجاع الباقي بعد قسمة القيمة على صفر. وبالتالي، يتم إرجاع 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 واحدة تُرجع خطأ. توفر 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؟
قبل الختام، دعونا نلقي نظرة على بعض الأمثلة الشائعة للحصول على ليس رقمًا (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