John Squirrels
ระดับ
San Francisco

NaN ใน Java

เผยแพร่ในกลุ่ม
ในภาษาจาวา “NaN” ย่อมาจาก “Not a Number” ไม่ใช่ประเภทของข้อยกเว้น แต่น่าประหลาดใจที่ประเภทข้อมูลของ NaN เป็นตัวเลขด้วย แต่บ่อยครั้งที่โปรแกรมเมอร์มือใหม่ได้รับมันโดยไม่ได้ตั้งใจ พวกเขาก็จะนำไปใช้ในการคำนวณต่อไป ดังนั้น ชนิดข้อมูลที่เข้ากันไม่ได้ใน Java เมื่อใช้ร่วมกันอาจทำให้เกิดข้อผิดพลาดแบบโยนได้ นอกจากนี้ยังเห็นได้ทั่วไปซึ่งjava.lang.ArithmeticException: / by zeroถือว่าเหมือนกับ NaN อย่างไรก็ตาม Java ปฏิบัติต่อทั้งสองต่างกัน งงพอไหม? เพื่อความเข้าใจที่ครอบคลุมของคุณ เราจะแยกความแตกต่างระหว่างสิ่งเหล่านี้ ในตอนท้ายของบทความนี้ คุณจะได้เรียนรู้เกี่ยวกับการดำเนินการที่เป็นไปได้ซึ่งไม่ใช่ตัวเลข (nan) และวิธีการง่ายๆ ในการจัดการ

แนน คืออะไร?

แล้ว NaN คืออะไร? “NaN” อย่างที่หลายๆ คนคาดเดา ใช้แทนคำว่า “Not a Number” ในภาษาจาวา เป็นค่าทศนิยมพิเศษเพื่อแสดงถึงการล้นและข้อผิดพลาด มันถูกสร้างขึ้นเมื่อเลขทศนิยมถูกหารด้วยศูนย์หรือถ้าคำนวณรากที่สองของจำนวนลบ 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 มีค่าทศนิยมและค่าสองเท่าพิเศษสามค่าเพื่อจัดการกับกรณีขอบเขต:
  • อินฟินิตี้บวก
  • อินฟินิตี้เชิงลบ
  • น่าน
ผลลัพธ์ของการหารจำนวนบวกด้วย 0 คือจำนวนเต็มบวก ในทำนองเดียวกัน ค่าอนันต์ติดลบเป็นผลมาจากการหารจำนวนลบด้วยศูนย์ โปรดทราบว่าค่าทศนิยมทั้งหมดใช้ได้กับประเภทข้อมูลสองเท่าเช่นกัน ความแม่นยำที่จำกัดของการลอยบางครั้งก็ไม่เพียงพอ อย่างไรก็ตาม เราจะมาดูกันว่า NaN ทำงานอย่างไรสำหรับทั้ง float และ double ในส่วนถัดไป

วิธี isNaN() คืออะไร?

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

บทสรุป

หลังจากดูการดำเนินการจำนวนมากที่สร้าง NaN แล้ว ตอนนี้คุณต้องคุ้นเคยกับมันแล้ว ในตอนแรกอาจทำให้คุณงง แต่ก็ไม่มีอะไรซับซ้อนในการจัดการกับสิ่งนี้ การพัฒนานิสัยเล็กๆ น้อยๆ ในการตรวจสอบว่าค่าไม่ใช่ NaN ในการคำนวณแบบ double/floating point จะช่วยให้คุณไม่ต้องยุ่งยากมากมาย แม้ว่าคุณจะลืมสิ่งนี้ในตอนแรก แต่ก็ไม่เป็นไร คุณสามารถอ่านบทความนี้เพื่อแก้ไขปัญหาเล็กน้อยได้ตลอดเวลา การสร้างโค้ดที่คอมไพล์ได้และปราศจากข้อผิดพลาดในครั้งเดียวนั้นมาจากประสบการณ์หลายปี ดังนั้นมาทำให้มือของเราสกปรกในโค้ดและสร้างสิ่งที่ยอดเยี่ยม!
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION