ทำไมการพิมพ์ NaN ถึงส่งกลับ 'number'


166

เพิ่งออกมาจากความอยากรู้

ดูเหมือนว่าtypeof NaNจะไม่เป็นจำนวนมาก ชอบNaN === NaNหรือNaN == NaNกลับเท็จโดยวิธี นี่เป็นหนึ่งในลักษณะเฉพาะของจาวาสคริปต์หรือจะมีเหตุผลสำหรับสิ่งนี้หรือไม่?

แก้ไข: ขอบคุณสำหรับคำตอบของคุณ ไม่ใช่เรื่องง่ายเลยที่จะพาคนรอบตัวคุณ อ่านคำตอบและวิกิที่ฉันเข้าใจมากขึ้น แต่ยังคงเป็นประโยคเช่น

การเปรียบเทียบกับ NaN จะส่งคืนผลลัพธ์ที่ไม่ได้เรียงลำดับเสมอแม้ว่าจะเปรียบเทียบกับตัวเองก็ตาม เพรดิเคตการเปรียบเทียบเป็นการส่งสัญญาณหรือไม่ใช่การส่งสัญญาณเวอร์ชันการส่งสัญญาณจะส่งสัญญาณข้อยกเว้นที่ไม่ถูกต้องสำหรับการเปรียบเทียบดังกล่าว ภาคความเท่าเทียมกันและความไม่เท่าเทียมกันเป็นสัญญาณที่ไม่ส่งสัญญาณดังนั้น x = x กลับเท็จสามารถใช้ในการทดสอบว่า x เป็น NaN ที่เงียบสงบ

ทำให้หัวของฉันหมุน หากใครบางคนสามารถแปลสิ่งนี้ในภาษามนุษย์ (ตรงข้ามกับพูดนักคณิตศาสตร์) ที่อ่านได้ฉันจะเป็นเรื่องน่ากลัว


17
+1: "NaN เป็นตัวเลข แต่ไม่ใช่ -a-number ฮัม ... อะไรนะ!"
ereOn

11
เพื่อความสนุกสนานเป็นพิเศษ (NaN! == NaN) == จริง
Alex K.

1
สนุกยิ่งขึ้น (แต่เข้าใจได้ว่าจะคิด isNaN คืนค่าบูลีน): isNaN (parseInt ('nodice')) === isNaN (parseInt ('someOtherNaN')) === จริง;
KooiInc

1
หากใช้ jQuery ฉันชอบที่จะisNumericตรวจสอบประเภท: $.isNumeric(NaN); return false โดยที่ as $.type(NaN);ส่งคืนหมายเลข api.jquery.com/jQuery.isNumeric
Justin

3
ในฐานะนักคณิตศาสตร์มืออาชีพฉันต้องบอกว่าประโยคนั้นมีเหมือนกันเล็กน้อยกับภาษาของคณิตศาสตร์ที่แม่นยำ
Dmitri Zaitsev

คำตอบ:


53

มันหมายถึงไม่ใช่จำนวน มันไม่ใช่ลักษณะเฉพาะของจาวาสคริปต์ แต่เป็นหลักการทางวิทยาศาสตร์คอมพิวเตอร์ทั่วไป

จากhttp://en.wikipedia.org/wiki/NaN :

มีการดำเนินการสามประเภทที่ส่งคืนน่าน:

การดำเนินการกับ NaN อย่างน้อยหนึ่งตัวถูกดำเนินการ

แบบฟอร์มไม่แน่นอน

  • ดิวิชั่น 0/0, ∞ / ∞, ∞ / −∞, −∞ / ∞และ −∞ / −∞
  • การคูณ 0 ×∞และ 0 × −∞
  • พลัง 1 ^ ∞
  • การบวก∞ + (−∞), (−∞) + ∞และการลบที่เทียบเท่า

การทำงานจริงด้วยผลลัพธ์ที่ซับซ้อน:

  • สแควร์รูทของจำนวนลบ
  • ลอการิทึมของจำนวนลบ
  • แทนเจนต์ของพหุคูณ 90 องศา (หรือπ / 2 เรเดียน)
  • ค่า inverse sine หรือ cosine ของตัวเลขซึ่งน้อยกว่า −1 หรือมากกว่า +1

ค่าทั้งหมดเหล่านี้อาจไม่เหมือนกัน การทดสอบอย่างง่ายสำหรับ NaN คือการทดสอบvalue == valueเป็นเท็จ


46
การทดสอบที่ง่ายยิ่งขึ้นคือisNaN(value)
Alsciende

4
@Alsciende มันไม่เทียบเท่ากัน isNaN(undefined)ส่งคืนtrueแต่undefined == undefinedก็เป็นจริงเช่นกัน กันไปสำหรับทุกประเภทหมายเลขอื่น ๆ nullที่ไม่ใช่ยกเว้น
Andy

7
ในคำอื่น ๆvalue !== valueน่าจะเป็นวิธีที่สั้นที่สุดเพื่อทดสอบว่าเป็นจริงvalue NaN
Andy

1
ดูเหมือนว่าคุณจะถูก @Andy ตอนนี้เป็นเรื่องแปลก
Alsciende

2
วลี "ค่าเหล่านี้อาจไม่เหมือนกัน" ไม่มีความหมายเนื่องจากไม่มีค่าเหล่านั้น
Dmitri Zaitsev

103

ดีNaNยังคงเป็นตัวเลขชนิดแม้จะมีความจริงที่มันเป็นจริงหมายถึงไม่-A-จำนวน :-)

NaNjust หมายถึงค่าที่ระบุไม่สามารถแสดงได้ภายในข้อ จำกัด ของประเภทตัวเลข (แม้ว่าอาจกล่าวได้ว่าเป็นตัวเลขทั้งหมดที่ต้องปัดเศษให้พอดี แต่NaNเป็นกรณีพิเศษ)

ค่าเฉพาะNaNนั้นไม่ถือว่ามีค่าเท่ากับค่าอื่นNaNเนื่องจากค่าอาจแตกต่างกัน อย่างไรก็ตามNaNยังคงเป็นประเภทตัวเลขเช่นเดียวกับ 2718 หรือ 31415


ตามคำถามที่อัปเดตของคุณเพื่ออธิบายในแง่ของคนธรรมดา:

การเปรียบเทียบกับ NaN จะส่งคืนผลลัพธ์ที่ไม่ได้เรียงลำดับเสมอแม้ว่าจะเปรียบเทียบกับตัวเองก็ตาม เพรดิเคตการเปรียบเทียบเป็นการส่งสัญญาณหรือไม่ใช่การส่งสัญญาณเวอร์ชันการส่งสัญญาณจะส่งสัญญาณข้อยกเว้นที่ไม่ถูกต้องสำหรับการเปรียบเทียบดังกล่าว ภาคความเท่าเทียมกันและความไม่เท่าเทียมกันเป็นสัญญาณที่ไม่ส่งสัญญาณดังนั้น x = x กลับเท็จสามารถใช้ในการทดสอบว่า x เป็นน่านที่เงียบสงบ

ทั้งหมดนี้หมายถึง (แบ่งออกเป็นส่วน ๆ ):

การเปรียบเทียบกับ NaN จะส่งคืนผลลัพธ์ที่ไม่ได้เรียงลำดับเสมอแม้ว่าจะเปรียบเทียบกับตัวเองก็ตาม

โดยทั่วไปNaNไม่เท่ากับหมายเลขอื่น ๆ รวมถึงอีกNaNและยังรวมถึงตัวเอง

เพรดิเคตการเปรียบเทียบเป็นการส่งสัญญาณหรือไม่ใช่การส่งสัญญาณเวอร์ชันการส่งสัญญาณจะส่งสัญญาณข้อยกเว้นที่ไม่ถูกต้องสำหรับการเปรียบเทียบดังกล่าว

ความพยายามในการทำการเปรียบเทียบ (น้อยกว่ามากกว่าและอื่น ๆ ) ระหว่าง a NaNและตัวเลขอื่นอาจส่งผลให้เกิดข้อยกเว้นที่ถูกส่งออกไป (การส่งสัญญาณ) หรือเพิ่งได้รับผลที่ผิดพลาด (ไม่ใช่สัญญาณหรือเงียบ)

ภาคความเท่าเทียมกันและความไม่เท่าเทียมกันเป็นสัญญาณที่ไม่ส่งสัญญาณดังนั้น x = x กลับเท็จสามารถใช้ในการทดสอบว่า x เป็นน่านที่เงียบสงบ

การทดสอบความเสมอภาค (เท่ากับไม่เท่ากับ) จะไม่ส่งสัญญาณดังนั้นการใช้มันจะไม่ทำให้เกิดข้อยกเว้น หากคุณมีหมายเลขปกติxก็x == xจะเป็นจริงเสมอ ถ้าxเป็นNaNแล้วx == xจะเป็นเท็จเสมอ มันทำให้คุณมีวิธีในการตรวจจับNaNได้ง่าย ๆ (เงียบ ๆ )


1
คำอธิบายที่ดีแม้ว่าฉันจะไม่เห็นด้วยในสองประโยคสุดท้าย: วิธีที่ดีกว่าในการตรวจสอบว่า x คือ NaN ใช้ฟังก์ชัน isNaN () หรือไม่
Carlos Barcelona

@DominicRodger นี่เป็นวิธีที่ฉันคิดเกี่ยวกับมัน: typeof a === 'number'หมายถึง "a ถูกเก็บไว้ภายในเป็น IEEE 754 float"
Andy

ทำไมถึงInfinity === InfinityกลับมาtrueหากInfinityสามารถผลิตได้โดยค่าที่แตกต่าง: 1.0 / 0.0 หรือ 2.0 / 0.0?
Hashem Qolami

1
@Hashem อาจเป็นเพราะพวกเขาถือว่าอินฟินิตี้เดียวกัน การรักษาด้วยการหารเป็นการลบซ้ำ ๆ มันไม่ได้ทำให้แตกต่างไม่ว่าคุณจะเริ่มต้นที่สองหรือหนึ่งก็เป็นจำนวนขั้นตอนเดียวกันที่ต้องใช้ในการเข้าถึง (หรืออย่างแม่นยำมากขึ้นไม่ถึง) ศูนย์ ฉันเข้าใจว่าปรมาจารย์คณิตศาสตร์มีคลาสที่แตกต่างกันมากมาย แต่ (1) ฉันสงสัย1/0และ2/0นอนในชั้นเดียวกันและ (2) มีอินฟินิตี้คลาสเดียวใน IEEE754 (นอกเหนือ+/-จากหลักสูตร)
paxdiablo

1
ฉันไม่ได้ตระหนักถึงวิธีการกำหนด "ตัวเลขจริง" ที่ยอดเยี่ยมเหล่านี้ในวิธีที่มีความหมายใด ๆ ในวิชาคณิตศาสตร์บันทึกและรากของเนกาทีฟสามารถทำได้โดยใช้วิธีการขยายของจำนวนจริงเป็นจำนวนเชิงซ้อนที่พวกเขาประเมินค่าหลายค่าและ0/0ไม่ได้กำหนดไว้ในวิธีที่มีความหมายอื่น ๆ นอกเหนือจากการพูดว่า "มูลค่า" เป็นทั้งชุด ของตัวเลข และแม้ว่าพวกเขาถูกกำหนดไว้ยังคงประเมินMath.log(-1) == Math.log(-1) falseดังนั้นไม่เพียง แต่ไม่มี "ตัวเลขจริง" ที่นอกเหนือไปจากนั้นNaNแม้ว่าจะมีอยู่ก็ตามพวกเขาไม่ได้ใช้สำหรับการเปรียบเทียบ
Dmitri Zaitsev

20

มาตรฐาน ECMAScript (JavaScript) ระบุว่าNumbersเป็นIEEE 754ลอยซึ่งรวมNaNเป็นค่าที่เป็นไปได้

ECMA 262 5e มาตรา 4.3.19 : ค่าตัวเลข

ค่าดั้งเดิมที่สอดคล้องกับรูปแบบไบนารี 64 บิตความแม่นยำสองเท่าของค่า IEEE 754

ECMA 262 5e มาตรา 4.3.23 : น่าน

ค่าตัวเลขที่เป็นค่า IEEE 754 "Not-a-Number"

IEEE 754บน Wikipedia

มาตรฐาน IEEE สำหรับการคำนวณเลขทศนิยมเป็นมาตรฐานทางเทคนิคที่จัดตั้งขึ้นโดยสถาบันวิศวกรไฟฟ้าและอิเล็กทรอนิกส์และมาตรฐานที่ใช้กันอย่างแพร่หลายสำหรับการคำนวณทศนิยม [... ]

มาตรฐานกำหนด

  • รูปแบบทางคณิตศาสตร์ : ชุดของข้อมูลเลขฐานสองและทศนิยมซึ่งประกอบด้วยตัวเลขที่ จำกัด (รวมทั้งเลขศูนย์และตัวเลขที่ไม่ได้ลงนาม), อินฟินิตี้และค่าพิเศษ "ไม่ใช่ตัวเลข" (NaNs)

[ ... ]


8

typeof NaNส่งคืน'number'เนื่องจาก:

  • ข้อมูลจำเพาะ ECMAScript บอกว่าชนิด Number มี NaN:

    4.3.20 ประเภทของตัวเลข

    ชุดของค่าตัวเลขที่เป็นไปได้ทั้งหมดรวมถึงค่า“ Not-a-Number” (NaN) พิเศษ, อนันต์บวกและอินฟินิตี้ลบ

  • ดังนั้นtypeofส่งคืนตาม:

    11.4.3 ผู้ประกอบการ typeof

    การผลิตUnary Expression : typeof Unary Expressionได้รับการประเมินดังนี้:

    1. ให้valเป็นผลลัพธ์ของการประเมินUnaryExpression UnaryExpression
    2. ถ้าType ( val ) เป็นการอ้างอิงแล้ว
      1. ถ้าIsUnresolvableReference ( val ) เป็นจริงให้ส่งคืน"undefined"กลับ
      2. ให้valเป็นGetValue ( val )
    3. กลับสตริงกำหนดโดยประเภท ( Val ) ตามตารางที่ 20

                    Table 20 — typeof Operator Results
    ==================================================================
    |        Type of val         |              Result               |
    ==================================================================
    | Undefined                  | "undefined"                       |
    |----------------------------------------------------------------|
    | Null                       | "object"                          |
    |----------------------------------------------------------------|
    | Boolean                    | "boolean"                         |
    |----------------------------------------------------------------|
    | Number                     | "number"                          |
    |----------------------------------------------------------------|
    | String                     | "string"                          |
    |----------------------------------------------------------------|
    | Object (native and does    | "object"                          |
    | not implement [[Call]])    |                                   |
    |----------------------------------------------------------------|
    | Object (native or host and | "function"                        |
    | does implement [[Call]])   |                                   |
    |----------------------------------------------------------------|
    | Object (host and does not  | Implementation-defined except may |
    | implement [[Call]])        | not be "undefined", "boolean",    |
    |                            | "number", or "string".            |
    ------------------------------------------------------------------

พฤติกรรมนี้เป็นไปตามมาตรฐาน IEEE สำหรับเลขทศนิยม (IEEE 754) :

4.3.19 ค่าตัวเลข

ค่าดั้งเดิมที่สอดคล้องกับรูปแบบไบนารี 64 บิตความแม่นยำสองเท่าของค่า IEEE 754

4.3.23 NaN

ค่าตัวเลขที่เป็นค่า“ Not-a-Number” ของ IEEE 754

8.5 ประเภทตัวเลข

ประเภท Number มีค่า 18437736874454810627 (นั่นคือ 2 53 −2 64 +3) ซึ่งแสดงถึงรูปแบบ 64 บิตที่มีความแม่นยำสองเท่าของค่า IEEE 754 ตามที่ระบุในมาตรฐาน IEEE สำหรับเลขฐานสองทศนิยม นั่นคือ 2 53 −2) ค่า“ Not-a-Number” ที่แตกต่างกันของมาตรฐาน IEEE แสดงด้วย ECMAScript ในรูปแบบNaNพิเศษค่า(โปรดทราบว่าค่าNaNนั้นสร้างขึ้นโดยนิพจน์โปรแกรมNaN)


5

NaN เป็นค่าทศนิยมที่ถูกต้อง ( http://en.wikipedia.org/wiki/NaN )

และ NaN === NaN เป็นเท็จเพราะไม่จำเป็นต้องเป็นตัวเลขเดียวกัน


1
ขออภัยที่ฉันต้องบอกว่าไม่ใช่วิธีที่ดีที่จะคิดเกี่ยวกับมัน "ไม่จำเป็นต้องเป็นตัวเลขที่ไม่เหมือนกัน" ไม่ได้หมายความว่าพวกเขาจะแตกต่างกันเสมอและการเปรียบเทียบพวกเขาควรให้เท็จ เป็นการดีที่สุดที่จะไม่ให้ NaN เป็นปริมาณและคิดว่ามันเป็นเรื่องแปลกในฐานความรู้ของเรา
เดฟ

1
เหตุInfinityใดจึงเหมือนกันทั้งหมด ความคิดใด ๆ
Hashem Qolami

5

NaN != NaNเพราะพวกเขาไม่จำเป็นที่ไม่ใช่หมายเลขเดียวกัน ดังนั้นมันจึงสมเหตุสมผลมาก ... และทำไมลอยมีทั้ง +0.00 และ -0.00 ที่ไม่เหมือนกัน การปัดเศษอาจทำได้จริง ๆ แล้วไม่เป็นศูนย์

สำหรับ typeof นั้นขึ้นอยู่กับภาษา และภาษาส่วนใหญ่จะบอกว่า NaN เป็นทศนิยมสองเท่าหรือตัวเลขขึ้นอยู่กับว่าพวกเขาจำแนกมันอย่างไร ... ฉันรู้ว่าไม่มีภาษาใดที่จะกล่าวได้ว่านี่เป็นประเภทที่ไม่รู้จักหรือไม่มีค่า


1
ehr, พิจารณา: var x = parseInt ('ไม่มีลูกเต๋า'), y = x; ตอนนี้ฉันจะบอกว่า NaN ทั้งสองเหมือนกันหรือไม่ แต่ไม่ x === y กลับเท็จเช่นกัน
KooiInc

ใช่ แต่คุณไม่สามารถมั่นใจได้และดังนั้นพวกเขาจะไม่เหมือนกัน มันเป็นตรรกะเดียวกันกับตรรกะ NULLable ในฐานข้อมูล แม้ว่าหลายคนคิดว่าพวกเขาเป็นเช่นเดียวกับพอยน์เตอร์พอยน์เตอร์จากภาษาโปรแกรมอื่น ๆ พวกเขา infact มีความหมายที่แตกต่างกันโดยสิ้นเชิง พวกเขาคือ "ไม่รู้จัก" และทำให้ค่า NULL หนึ่งค่าเมื่อเปรียบเทียบกับค่าอื่นเป็นเท็จเสมอ การคำนวณค่า NULL จะจบลงด้วยผลลัพธ์ NULL ลองดูจากมุมมองของค่าที่เรียกว่า UNKNOWN แทน
Cine

ในฐานะที่เป็นประเภทnumber, NaNดั้งเดิมและด้วยเหตุนี้กำหนดไม่ซ้ำกันโดยความคุ้มค่า
Dmitri Zaitsev

4

NaNย่อมาจากNot a Numberไม่ใช่ตัวเลขมันเป็นค่าของชนิดข้อมูลตัวเลข (โดยทั่วไปจะเป็นชนิดจุดลอยตัว แต่ไม่เสมอไป) ที่แสดงผลลัพธ์ของการดำเนินการที่ไม่ถูกต้องเช่นการหารด้วยศูนย์

แม้ว่าชื่อของมันจะบอกว่ามันไม่ใช่ตัวเลข แต่ชนิดข้อมูลที่ใช้เพื่อเก็บมันเป็นชนิดตัวเลข ดังนั้นใน JavaScript การขอประเภทข้อมูลNaNจะส่งคืนnumber(ตามที่alert(typeof(NaN))อธิบายไว้อย่างชัดเจน)


ที่จริงแล้วการหารด้วยศูนย์จะถูกประเมินเป็นInfinityไม่ใช่NaN
Dmitri Zaitsev

2

Javascript ใช้ NaN เพื่อแสดงสิ่งที่พบซึ่งไม่สามารถแสดงด้วยวิธีอื่นได้ มันไม่ได้หมายความว่ามันไม่ใช่ตัวเลข มันเป็นวิธีที่ง่ายที่สุดในการอธิบายการเผชิญหน้า NaN หมายความว่ามันหรือวัตถุที่อ้างถึงไม่สามารถแสดงด้วยวิธีอื่นใดโดยจาวาสคริปต์ สำหรับวัตถุประสงค์ในทางปฏิบัติทั้งหมดนั้นคือ 'ไม่ทราบ' การเป็น 'ไม่รู้จัก' ไม่สามารถบอกคุณได้ว่ามันคืออะไรและถึงแม้ว่ามันจะเป็นตัวของมันเองก็ตาม มันไม่ได้เป็นวัตถุที่ได้รับมอบหมาย มันสามารถบอกคุณได้ว่ามันไม่ได้เป็นอะไรและไม่สามารถอธิบายได้ในเชิงคณิตศาสตร์ในภาษาการเขียนโปรแกรมเท่านั้น เนื่องจากคณิตศาสตร์เป็นเรื่องของตัวเลขจาวาสคริปต์จึงแสดงถึงความว่างเปล่าเหมือน NaN ไม่ได้หมายความว่ามันไม่ใช่ตัวเลข หมายความว่าเราไม่สามารถอ่านวิธีอื่นที่เหมาะสมได้ นั่นเป็นเหตุผลที่มันสามารถ ' ไม่เท่ากัน เพราะมันไม่


2

ชื่อที่ดีกว่าสำหรับNaNการอธิบายความหมายของมันอย่างแม่นยำมากขึ้นและน้อยพลุกพล่านจะเป็นข้อยกเว้นตัวเลข เป็นข้อยกเว้นอีกประเภทหนึ่งที่ปลอมแปลงว่ามีประเภทแบบดั้งเดิม (โดยการออกแบบภาษา) ซึ่งในขณะเดียวกันก็ไม่ถือว่าเป็นวัตถุดั้งเดิมในการเปรียบเทียบตนเองที่ผิดพลาด ดังนั้นความสับสน และตราบใดที่ภาษา "จะไม่ทำให้จิตใจ" เลือกระหว่างวัตถุยกเว้นที่เหมาะสมและตัวเลขดั้งเดิมความสับสนจะยังคงอยู่

ความไม่เท่าเทียมกันที่น่าอับอายของNaNตัวเองทั้งสอง==และ===เป็นการรวมตัวกันของการออกแบบที่ทำให้เกิดความสับสนบังคับให้วัตถุข้อยกเว้นนี้กลายเป็นประเภทดั้งเดิม ซึ่งจะเป็นการแบ่งหลักการพื้นฐานว่าดั้งเดิมจะถูกกำหนดโดยไม่ซ้ำกันโดยความคุ้มค่า หากNaNต้องการถูกมองว่าเป็นข้อยกเว้น (ซึ่งอาจมีหลายแบบ) ก็ไม่ควร "ขาย" เป็นแบบดั้งเดิม และถ้ามันต้องการที่จะเป็นแบบดั้งเดิมหลักการนั้นจะต้องถือ ตราบใดที่มันยังขาดอยู่ใน JavaScript และเราไม่สามารถตัดสินใจได้ระหว่างสองความสับสนที่นำไปสู่ภาระการรับรู้ที่ไม่จำเป็นสำหรับทุกคนที่เกี่ยวข้องจะยังคงอยู่ อย่างไรก็ตามซึ่งง่ายต่อการแก้ไขโดยการเลือกระหว่างสองตัวเลือก:

  • ทำให้NaNวัตถุข้อยกเว้นพิเศษที่มีข้อมูลที่เป็นประโยชน์เกี่ยวกับวิธีการยกเว้นเกิดขึ้นเมื่อเทียบกับการโยนข้อมูลนั้นเป็นสิ่งที่มีการใช้งานในปัจจุบันนำไปสู่รหัสที่ยากต่อการแก้ปัญหา;
  • หรือสร้างNaNเอนทิตีของประเภทดั้งเดิมnumber(ซึ่งอาจเรียกว่า "ตัวเลข" น้อยกว่าอย่างสับสน) ซึ่งในกรณีนี้มันควรจะเท่ากันและไม่สามารถมีข้อมูลอื่นใดได้ เห็นได้ชัดว่าเป็นตัวเลือกที่ด้อยกว่า

ประโยชน์เฉพาะเท่าที่จะนึกออกการบังคับให้NaNเข้าไปในnumberประเภทคือความสามารถที่จะโยนมันกลับเข้ามาในการแสดงออกเชิงตัวเลขใด ๆ ซึ่งทำให้ตัวเลือกที่เปราะบางเพราะผลลัพธ์ของการแสดงออกเชิงตัวเลขใด ๆ ที่มีNaNจะเป็นNaNหรือนำไปสู่ผลลัพธ์ที่ไม่สามารถคาดการณ์ได้เช่นNaN < 0การประเมินถึงfalseคือกลับมาbooleanแทนที่จะเก็บข้อยกเว้น

และแม้ว่า "สิ่งต่าง ๆ เป็นอย่างที่เป็นอยู่" แต่ก็ไม่มีอะไรขัดขวางเราจากการแยกแยะความแตกต่างที่ชัดเจนสำหรับตัวเราเองเพื่อช่วยให้รหัสของเราสามารถคาดเดาได้ง่ายขึ้นและ debuggable ได้ง่ายขึ้น ในทางปฏิบัตินั่นหมายถึงการระบุข้อยกเว้นเหล่านั้นและจัดการกับพวกเขาเป็นข้อยกเว้น ซึ่งน่าเสียดายที่หมายถึงรหัสเพิ่มเติม แต่หวังว่าจะลดลงโดยเครื่องมือเช่น TypeScript ของ Flowtype

และจากนั้นเราต้องยุ่งเงียบ VS มีเสียงดัง aka ส่งสัญญาณNaNความแตกต่าง ซึ่งจริงๆแล้วเกี่ยวกับวิธีการจัดการข้อยกเว้นไม่ใช่ข้อยกเว้นตัวเองและไม่มีอะไรแตกต่างจากข้อยกเว้นอื่น ๆ

ในทำนองเดียวกันInfinityและ+Infinityเป็นองค์ประกอบของประเภทตัวเลขที่เกิดขึ้นในการขยายสายจริงแต่พวกเขาไม่ใช่ตัวเลขจริง ศาสตร์ที่พวกเขาสามารถแสดงโดยลำดับของจำนวนจริงมาบรรจบกันอย่างใดอย่างหนึ่งหรือ+-Infinity


1

นี่เป็นเพียงเพราะNaNเป็นคุณสมบัติของวัตถุหมายเลขใน JS มันไม่ได้เกี่ยวข้องกับการเป็นตัวเลข


เช่นเดียวกับวัตถุอื่น ๆ Number สามารถมีคุณสมบัติประเภทใดก็ได้ Number.fu = "bar"; alert(typeof Number.fu);
Alsciende

NaNไม่ใช่ค่าที่เก็บไว้Number.NaNไม่ว่าจะเป็นอะไรก็ตาม NaNเป็นค่าดั้งเดิมของ Number type และยิ่งไปกว่านั้นคุณค่าของNumber.NaNมันคือNaNแต่นั่นไม่เกี่ยวข้องกัน
Oriol

1

วิธีที่ดีที่สุดที่จะคิดว่าน่านก็คือว่ามันไม่ได้เป็นที่รู้จักกันจำนวน นั่นเป็นเหตุผลที่ NAN! = NAN เพราะแต่ละค่า NAN แสดงถึงจำนวนที่ไม่รู้จัก NAN นั้นจำเป็นเพราะตัวเลขจุดลอยตัวมีช่วงของค่าที่ จำกัด ในบางกรณีการปัดเศษเกิดขึ้นเมื่อบิตที่ต่ำกว่าหายไปซึ่งนำไปสู่สิ่งที่ดูเหมือนไร้สาระเช่น 1.0 / 11 * 11! = 1.0 คุณค่าที่มีขนาดใหญ่จริงๆซึ่งมากกว่านั้นคือ NAN ซึ่งเป็นตัวอย่างที่สมบูรณ์แบบ

เนื่องจากเรามีเพียงสิบนิ้วเท่านั้นที่พยายามแสดงค่าที่มากกว่า 10 เป็นไปไม่ได้ซึ่งหมายความว่าค่าดังกล่าวต้องเป็น NAN เพราะเราสูญเสียมูลค่าที่แท้จริงของค่านี้มากกว่า 10 ค่า สิ่งเดียวกันนี้เป็นจริงของค่าจุดลอยตัวที่ค่าเกินขีด จำกัด ของสิ่งที่สามารถเก็บได้ในการลอย


อินฟินิตี้ไม่ได้เป็นตัวแทนของ NaN ความพยายามในการแสดงตัวเลขนอกช่วงจะถูกปัดเศษลง (เป็น max / -inf) หรือ up (ถึง min / + inf)
OrangeDog


1

NaNเป็นตัวเลขจากมุมมองประเภท แต่ไม่ใช่จำนวนปกติเช่น 1, 2 หรือ 329131 ชื่อ"หมายเลขไม่"หมายถึงความจริงที่ว่าค่าที่แสดงนั้นเป็นพิเศษและเป็นเรื่องเกี่ยวกับโดเมนรูปแบบ IEEE ไม่ใช่ โดเมนภาษาจาวาสคริปต์


1

หากใช้ jQuery ฉันชอบisNumericตรวจสอบประเภทมากกว่า:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/


ขอบคุณชาย ฉันมีปัญหากับisNumberจากutilแพ็คเกจของ typescript ดีที่เรายังคงใช้jQueryในโครงการของเราดังนั้นใช้คำแนะนำของคุณแทน
Ashok MA

สำหรับการบันทึกภาพisNumberจากutilของ typescript ยังผลตอบแทนสำหรับtrue NaN
Ashok MA

0

Javascript มีประเภทข้อมูลตัวเลขเพียงประเภทเดียวซึ่งเป็นมาตรฐานความแม่นยำสองเท่าแบบ 64 บิต ทุกอย่างเป็นสองเท่า NaN เป็นค่าพิเศษสองเท่า แต่ก็เป็นสองเท่า

สิ่งที่parseIntทำคือ "cast" สตริงของคุณลงในชนิดข้อมูลตัวเลขดังนั้นผลลัพธ์จะเป็น"number" เสมอ หากสตริงต้นฉบับไม่สามารถวิเคราะห์ได้ค่าของมันจะเป็น NaN


0

NaN ยังคงเป็นประเภทตัวเลข แต่แสดงถึงค่าที่ไม่สามารถแทนตัวเลขที่ถูกต้องได้


0

เราอาจโต้แย้งว่า NaN เป็นวัตถุตัวพิมพ์เล็ก ในกรณีนี้วัตถุของ NaN แสดงถึงจำนวนที่ไม่สมเหตุสมผลทางคณิตศาสตร์ มีวัตถุกรณีพิเศษอื่น ๆ ในคณิตศาสตร์เช่น INFINITE และอื่น ๆ

คุณยังสามารถทำการคำนวณบางอย่างกับมันได้ แต่นั่นจะทำให้เกิดพฤติกรรมแปลก ๆ

ข้อมูลเพิ่มเติมที่นี่: http://www.concentric.net/~ttwang/tech/javafloat.htm (อิงจากจาวาไม่ใช่จาวาสคริปต์)


0

คุณต้องรัก Javascript มันมีนิสัยใจคอเล็กน้อยที่น่าสนใจ

http://wtfjs.com/page/13

นิสัยใจคอเหล่านี้ส่วนใหญ่สามารถอธิบายได้หากคุณหยุดทำงานตามหลักเหตุผลหรือถ้าคุณรู้ทฤษฎีจำนวนเล็กน้อย แต่อย่างไรก็ตามพวกเขายังสามารถจับคุณได้หากคุณไม่รู้เรื่อง

อย่างไรก็ตามฉันขอแนะนำให้อ่านส่วนที่เหลือของhttp://wtfjs.com/ - มีนิสัยใจคอที่น่าสนใจมากกว่าการพบสิ่งนี้!


0

ค่า NaN เป็น Number.NaN จริง ๆ ดังนั้นเมื่อคุณถามว่าเป็นตัวเลขมันจะตอบว่าใช่ คุณทำสิ่งที่ถูกต้องโดยใช้การโทร isNaN ()

สำหรับข้อมูล NaN ยังสามารถส่งคืนโดยการดำเนินการกับ Numbers ที่ไม่ได้กำหนดไว้เช่นดิวิชั่นด้วยเลขศูนย์หรือรากที่สองของจำนวนลบ


ในแง่ใดมันคือ "คุณค่า"? NaN == Number.NaNประเมินเพื่อfalse!
Dmitri Zaitsev

@DmitriZaitsev คุณอ่านกระทู้หรือไม่ และคุณเคยลองไหมถ้า (parseInt ("nan") == Number.NaN)? ลองด้วย! = และดูว่ามีอะไรบอกคุณบ้าง
Rob

ขออภัยลืมโง่NaN==NaNเป็นอยู่falseก็จะต้องได้รับซาดิสม์ผู้คิดค้นที่จะทำให้ทุกคนประสบ
Dmitri Zaitsev

0

ตัวอย่าง

ลองนึกภาพเราจะแปลงสตริงเป็นตัวเลข:

Number("string"); // returns NaN

เราเปลี่ยนชนิดข้อมูลเป็นตัวเลข แต่ค่าไม่ใช่ตัวเลข!


คุณดูเหมือนจะพลาดจุดของคำถาม NaNเป็นประเภทหมายเลข คำถามกำลังถามว่าทำไม
เควนติน

@Quentin ฉันอธิบายที่บรรทัดสุดท้าย
Amir Fo

-1

เป็นค่าพิเศษของชนิดตัวเลขเป็น POSITIVE_INFINITY

ทำไม? โดยการออกแบบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.