ทำไม parseInt (1/0, 19) ถึง 18 คืน


853

ผมมีปัญหาที่น่ารำคาญในJavaScript

> parseInt(1 / 0, 19)
> 18

ทำไมparseIntฟังก์ชั่นถึงกลับมา18?


3
น่าสนใจ แต่ทำไมปัญหานี้ถึงน่ารำคาญสำหรับคุณ คุณต้องจัดการกับ Infinity อย่างอื่นไหม? ถ้าเป็นเช่นนั้นifอาจช่วย
Thilo

254
คุณกำลังทำอะไรอยู่ที่ทำให้คุณต้องทำงานกับตัวเลขฐาน -19 หรือหารด้วยศูนย์!
Jack M

19
เมื่อคุณสับสนเกี่ยวกับ JS เพียงแค่กลับไปที่คำพูดนี้และจำไว้ว่าภาษาแช่งทั้งหมดได้รับการออกแบบและดำเนินการในเวลาน้อยกว่า 10 วัน (ตามบุคคลที่ทำ)
tylerl

32
จากคำถามที่พบบ่อย: "คุณควรถามคำถามที่ตอบได้จริงและปฏิบัติได้จริงตามปัญหาจริงที่คุณเผชิญอยู่" นี้ไม่ได้เป็นจริง "ปัญหาที่น่ารำคาญ" ที่คุณจริงใบหน้ามันเป็นตัวอย่างที่ไม่สมจริงที่ถูกลอยรอบอินเทอร์เน็ตตลอด
Jeremy Banks

2
หลามทำสิ่งเดียวกัน: int ('I', 19) == 18
oberhamsi

คำตอบ:


1292

ผลจากการมี1/0Infinity

parseIntถือว่าอาร์กิวเมนต์แรกมันเป็นสตริงซึ่งหมายความว่าแรกของทั้งหมดจะเรียกว่าการผลิตสตริงInfinity.toString() "Infinity"มันทำงานเหมือนกับว่าคุณขอให้มันแปลง"Infinity"ในฐาน 19 เป็นทศนิยม

นี่คือตัวเลขในฐาน 19 พร้อมกับค่าทศนิยม:

Base 19   Base 10 (decimal)
---------------------------
   0            0
   1            1
   2            2
   3            3
   4            4
   5            5
   6            6
   7            7
   8            8
   9            9
   a            10
   b            11
   c            12
   d            13
   e            14
   f            15
   g            16
   h            17
   i            18

สิ่งที่เกิดขึ้นถัดไปคือการparseIntสแกนอินพุต"Infinity"เพื่อค้นหาว่าส่วนใดของมันที่สามารถแยกวิเคราะห์และหยุดหลังจากที่รับรหัสแรกI(เพราะnไม่ใช่ตัวเลขที่ถูกต้องในฐาน 19)

ดังนั้นมันจะทำงานเหมือนกับว่าคุณโทรหาparseInt("I", 19)ซึ่งจะแปลงเป็นทศนิยม 18 ตามตารางด้านบน


32
parseInt('Infini',24)ลอง @mithunsatheesh
Supr

112
@mithunsatheesh: เพราะในฐาน 24 ยังเป็นหลักที่ถูกต้องเพื่อให้มันจริงจบลงด้วยการทำn parseInt("Infini", 24)
Jon

36
ทำไมบางคนต้องการ 'โปรแกรม' ในภาษาที่มีลักษณะเช่นนี้อยู่นอกเหนือฉัน
ฟราน Bouma

45
@FransBouma: JS มีความสวยงามในแบบของตัวเอง และจริงๆไม่มีส่วนใดของสิ่งที่เกิดขึ้นที่นี่ไม่มีเหตุผลในภาษาแบบไดนามิก
Jon

59
@ จอน: สิ่งประดิษฐ์นี้ไม่ได้เป็นผลมาจากภาษาแบบไดนามิก มันเป็นผลมาจากการพิมพ์หลวม ในภาษาไดนามิกที่พิมพ์อย่างเคร่งครัดการแปลงโดยนัยของ Infinity (float) เป็น "Infinity" (สตริง) จะไม่เกิดขึ้นเพื่อป้องกันความงี่เง่าแบบนี้
โกหกไรอัน

225

นี่คือลำดับเหตุการณ์:

  • 1/0 ประเมินให้ Infinity
  • parseIntอ่านInfinityและจดบันทึกอย่างมีความสุขที่I18 ในฐาน 19
  • parseInt ละเว้นส่วนที่เหลือของสตริงเนื่องจากไม่สามารถแปลงได้

โปรดทราบว่าคุณจะได้รับผลลัพธ์สำหรับฐานใด ๆ>= 19แต่ไม่ใช่สำหรับฐานด้านล่าง สำหรับฐาน>= 24คุณจะได้รับผลลัพธ์ที่มากขึ้นโดยnจะกลายเป็นตัวเลขที่ถูกต้อง ณ จุดนั้น


@Thilo BTW สิ่งที่จะเป็นเหตุผลว่าทำไมมันอาจหยุดที่ 19 ถ้าฐานของที่สูงกว่า? คุณรู้หรือไม่ JS ที่ยิ่งใหญ่ที่สุดสามารถตีความอะไรได้บ้าง
Arnthor

4
@Nordvind ฐานที่ใหญ่ที่สุดที่parseIntจะยอมรับคือ 36 เนื่องจากมี 26 ตัวอักษรในตัวอักษรภาษาอังกฤษและการประชุมคือการใช้ตัวเลขแล้วตัวอักษรเป็นชุดของตัวเลขที่ถูกต้องในฐานที่กำหนด
Craig Citro

4
ในหัวข้อ bullet # 2 ฉันขอแนะนำให้เปลี่ยนInfinityเป็น"Infinity"...
CJBS

38

หากต้องการเพิ่มคำตอบข้างต้น:

parseInt มีวัตถุประสงค์เพื่อแยกสตริงเป็นตัวเลข (เบาะแสอยู่ในชื่อ) ในสถานการณ์ของคุณคุณไม่ต้องการแยกวิเคราะห์เลยเนื่องจาก 1/0 มีตัวเลขอยู่แล้วดังนั้นมันจึงเป็นฟังก์ชั่นที่แปลกประหลาด หากคุณมีตัวเลข (ซึ่งคุณทำ) และต้องการแปลงให้เป็นฐานเฉพาะคุณควรใช้toString ด้วย radixแทน

var num = 1 / 0;
var numInBase19 = num.toString(19); // returns the string "Infinity"

13

เพื่อเพิ่มคำตอบข้างต้น

parseInt(1/0,19) เทียบเท่ากับ parseInt("Infinity",19)

ภายในฐาน 19 ตัวเลข0-9และ A-I (or a-i)เป็นตัวเลขที่ถูกต้อง ดังนั้นจาก "อินฟินิตี้" ใช้เวลาIของฐาน 19 และแปลงเป็นฐาน 10 ซึ่งกลายเป็น 18 จากนั้นก็พยายามที่จะใช้ตัวละครต่อไปคือnที่ไม่ได้อยู่ในฐาน 19 ดังนั้นทิ้งตัวละครต่อไป (ตามพฤติกรรมของจาวาสคริปต์ )

ดังนั้นถ้าคุณเขียนparseInt("Infinity",19)หรือ parseInt("I",19)หรือผลจะเป็นเช่นเดียวกันparseInt("i",19)18

ตอนนี้ถ้าคุณเขียนparseInt("I0",19)ผลลัพธ์จะ342 เป็นI X 19 (the base)^1 + 0 X 19^0 = 18 X 19^1 + 0 X 19^0= 18 X 19 + 0 X 1 =342

ในทำนองเดียวกันparseInt("I11",19)จะส่งผลให้6518

กล่าวคือ

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