В Java „NaN“ означава „Не е число“. Това не е вид изключение, по-скоро изненадващо, типът данни на NaN също е число. Но често, когато начинаещите програмисти го получат неволно, те го използват допълнително в своите изчисления. Следователно несъвместимите типове данни в Java, когато се използват заедно, могат да причинят възможна грешка. Също така често се вижда, че java.lang.ArithmeticException: / by zeroсе счита за същото като NaN. Java обаче ги третира по различен начин. Достатъчно озадачаващо? За вашето цялостно разбиране ще анализираме How те се различават един от друг. До края на тази статия ще научите за възможните операции, произвеждащи не число (nan), и някои лесни начини да се справите с това.

Какво е NaN?

И така, Howво е NaN? „NaN“, Howто много от вас се досещат, се използва за представяне на „Не е число“ в Java. Това е специална стойност с плаваща запетая за обозначаване на преливания и грешки. Генерира се, когато число с плаваща запетая се раздели на нула or ако се изчисли корен квадратен от отрицателно число. NaN в Java - 1Например, погледнете следния фрагмент.

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.
  • Вземането на mod на число с нула ще върне остатъка след разделяне на стойност на нула. Следователно NaN се връща.

Как NaN е различен от положителна и отрицателна безкрайност?

Съгласно спецификацията IEEE 754 има три специални стойности с плаваща запетая и двойна стойност за обработка на граничните случаи:
  • Положителна безкрайност
  • Отрицателна безкрайност
  • NaN
Резултатът от разделянето на положително число на 0 е положителна безкрайност. По същия начин, отрицателна безкрайност дава в резултат на разделяне на отрицателно число с нула. Моля, обърнете внимание, че всички стойности с плаваща запетая са приложими и за тип данни double. Ограничената прецизност на поплавъците понякога не е достатъчна. Въпреки това ще видим How NaN работи Howто за float, така и за double в по-късен раздел.

Какво представлява методът NaN()?

isNaN()е един от основните методи в Java за проверка дали е NaN стойност or не. Както обсъдихме три случая по-горе, време е да тестваме How методът 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 не е equals на друг NaN. По този принцип, ако сравнявате една стойност с друга, резултатът винаги е отрицателен. Тъй като NaN е неподреден, така че числено сравнение, включващо дори един NaN, връща false. Java предоставя Float.NaN и Double.NaN за постоянни полета в двата класа за извършване на сравнения. Можем да ги разграничим в два отделни сценария:
  • Вярно: Само в случай на неequalsство (!=)
  • 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 стойности?

Преди да приключим, нека да разгледаме някои често срещани примери за получаване на 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

Заключение

След като разгледахте многобройните операции, произвеждащи NaN, вече трябва да сте запознати с него. Първоначално може да ви озадачи, но няма нищо сложно да се справите с това. Като развиете малък навик да проверявате дали дадена стойност не е NaN в изчисления с двойна/плаваща запетая може да ви спести много неприятности. Дори ако забравите това първоначално, всичко е наред. Винаги можете да се консултирате с тази статия за отстраняване на незначителни проблеми. Създаването на компorруем code без грешки наведнъж идва след години опит. Така че нека си изцапаме ръцете в codeа и да изградим нещо страхотно!