در جاوا، "NaN" مخفف "Not a Number" است. این یک نوع استثنا نیست، بلکه با کمال تعجب، نوع داده NaN نیز یک عدد است. اما اغلب زمانی که برنامه نویسان تازه کار به طور ناخواسته آن را دریافت می کنند، بیشتر از آن در محاسبات خود استفاده می کنند. از این رو، انواع داده های ناسازگار در جاوا هنگامی که با هم استفاده می شوند می توانند باعث خطای پرتاب شونده شوند. همچنین معمولاً دیده می شود که
java.lang.ArithmeticException: / by zero
همان NaN در نظر گرفته می شود. با این حال، جاوا با هر دو آنها متفاوت رفتار می کند. به اندازه کافی گیج کننده؟ برای درک جامع شما، تفاوت این دو را با یکدیگر تشریح خواهیم کرد. در پایان این مقاله با عملیاتهای احتمالی که یک عدد (nan) تولید نمیکنند، و چند راه آسان برای مدیریت آن آشنا خواهید شد.
NaN چیست؟
بنابراین، NaN چیست؟ "NaN" همانطور که بسیاری از شما حدس زده اید، برای نشان دادن "عدد نیست" در جاوا استفاده می شود. این یک مقدار ممیز شناور ویژه برای نشان دادن سرریزها و خطاها است. وقتی یک عدد ممیز شناور بر صفر تقسیم شود یا جذر یک عدد منفی محاسبه شود، تولید می شود. برای مثال به قطعه زیر نگاهی بیندازید.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 در جاوا حل می شود.
- گرفتن mod از یک عدد با صفر، پس از تقسیم یک مقدار بر صفر، باقیمانده را برمی گرداند. بنابراین، NaN برگردانده می شود.
NaN چه تفاوتی با بی نهایت مثبت و منفی دارد؟
طبق مشخصات IEEE 754، سه مقدار ممیز شناور و مضاعف ویژه برای رسیدگی به موارد مرزی وجود دارد:- بی نهایت مثبت
- بی نهایت منفی
- NaN
روشNaN() چیست؟
isNaN()
یکی از روش های اساسی در جاوا برای بررسی اینکه آیا مقدار 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 منفرد، نادرست است. جاوا 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