แอปเครื่องคิดเลข? ใครๆ ก็ทำได้ไม่ใช่เหรอ?
(chadnauseam.com)"แอปเครื่องคิดเลข? ใครๆ ก็ทำได้ไม่ใช่เหรอ" → ที่จริงไม่ใช่เลย
- เครื่องคิดเลขต้องแสดงผลลัพธ์ของนิพจน์ทางคณิตศาสตร์ให้ถูกต้อง และเรื่องนี้ยากกว่าที่คิดมาก
- ในเครื่องคิดเลขของ iOS นั้น
(10^100) + 1 − (10^100)ถูกคำนวณผิดเป็น0 - แต่ Android แสดงผลถูกต้องเป็น 1 ซึ่งวิธีที่ทำได้นั้นเหลือเชื่อจริงๆ
Google และ Hans-J. Boehm
- Google จ้าง Hans-J. Boehm โปรแกรมเมอร์ชื่อดัง
- Boehm เป็นผู้เชี่ยวชาญที่นิยาม semantics ของตัวแปรที่ใช้ร่วมกันใน C++
- แต่ภารกิจที่เขาได้รับกลับเป็นการพัฒนาแอปเครื่องคิดเลขอย่างคาดไม่ถึง
ปัญหาของ floating-point
- ตัวเลขแบบ floating-point ไม่สามารถแทนค่าบางอย่างอย่างแม่นยำได้ เช่น
0.3หรือ10^100 - นั่นหมายความว่าเครื่องคิดเลขที่อิงกับ floating-point เพียงอย่างเดียวเชื่อถือไม่ได้
- หากต้องการการคำนวณที่แม่นยำ จำเป็นต้องใช้แนวทางอื่น
วิธีแก้ด้วย Bignum
- ปัญหาการคำนวณจำนวนเต็มแก้ได้ด้วย Bignum (จำนวนเต็มไม่จำกัดขนาด)
- Bignum คือชนิดข้อมูลจำนวนเต็มที่ขยายขนาดแบบไดนามิกตามหน่วยความจำที่มี
- ปัญหา
(10^100) + 1 - (10^100)แก้ได้ด้วย Bignum - แต่ยังไม่สามารถแก้ปัญหาการคำนวณเศษส่วนได้
เศษส่วนและจำนวนพีชคณิต
- เศษส่วน (ค่าอย่าง
3/4) แก้ได้โดยใช้ Bignum เก็บตัวเศษและตัวส่วน - แต่จำนวนอตรรกยะอย่าง π หรือรากที่สองของ 2 (
√2) ยังไม่สามารถแทนค่าได้ - Boehm จึงลองใช้การแทนค่าบนพื้นฐานของพหุนาม
- ตัวอย่าง:
√2สามารถแทนได้ด้วยสมการx² - 2 = 0 - แต่ π ก็ยังแทนด้วยวิธีนี้ไม่ได้
- ตัวอย่าง:
จำนวนจริงเชิงสร้างสรรค์ (Constructive Real Numbers)
- Boehm ศึกษาแนวคิด "Recursive Real Arithmetic (RRA)"
- วิธีนี้คือเมื่อผู้ใช้ระบุความแม่นยำที่ต้องการ ระบบจะคำนวณค่าให้อยู่ภายในขอบเขตความแม่นยำนั้น
- ตัวอย่าง: หากต้องการแทนค่า π ภายในความคลาดเคลื่อน
0.01ระบบจะคืนค่า3.14 - แต่แนวทางนี้ทำให้การเปรียบเทียบค่าอย่างแม่นยำเป็นเรื่องยาก
ปัญหาการแทนค่า 0 ที่แน่นอน
- วิธีแบบ RRA อาจแทน
1 - 1ไม่ใช่เป็น0แต่เป็น0.0000000001 - ซึ่งเป็นปัญหาในมุมมองประสบการณ์ผู้ใช้ (UX)
- Boehm จึงเริ่มร่วมมือกับนักวิจัยคนอื่นเพื่อหาทางแก้
อัลกอริทึม Richardson-Fitch
- ในปี 1994 Dan Richardson และ John Fitch แก้ปัญหาการเปรียบเทียบตัวเลขในชุดปฏิบัติการบางประเภทได้
- แต่อัลกอริทึมนี้ช้าเกินไปจนใช้งานจริงไม่ได้
- ตัวอย่างเช่น การตัดสินว่า
1 ≠ 1 - e^(-e^1000)ต้องใช้การคำนวณมากกว่าจำนวนอะตอมทั้งหมดในจักรวาล
การผสาน RRA กับการคำนวณจำนวนตรรกยะ
- Boehm เกิดไอเดียที่จะรวมข้อดีของ RRA และการคำนวณจำนวนตรรกยะเข้าด้วยกัน
- การคำนวณแบบง่าย (เช่น
6 × 9หรือ8 / 3) ใช้การคำนวณจำนวนตรรกยะ - จะใช้ RRA เฉพาะเมื่อมีจำนวนอตรรกยะเข้ามาเกี่ยวข้อง
- สุดท้ายจึงแทนตัวเลขในรูป จำนวนตรรกยะ × จำนวนจริง
การแทนค่าเชิงสัญลักษณ์ (Symbolic Representation)
- ตัวเลขพิเศษอย่าง π และ
√2ใช้การแทนค่าเชิงสัญลักษณ์แทน RRA - ตัวอย่าง: π ถูกเก็บเป็นสัญลักษณ์ "π" และจะแปลงเป็นตัวเลขเมื่อจำเป็นเท่านั้น
- ไม่ใช่แค่การบวก ลบ คูณ หารเท่านั้น แต่ยังรวมถึงฟังก์ชันตรีโกณมิติ (sin, cos, tan), ลอการิทึม และฟังก์ชันเลขยกกำลังที่ใช้การแทนค่าเชิงสัญลักษณ์ด้วย
วิธีแก้สุดท้าย
- ตัวเลขทั้งหมดถูกเก็บในรูป จำนวนตรรกยะ × จำนวนจริง (การแทนค่าเชิงสัญลักษณ์หรือ RRA)
- ใช้การคำนวณจำนวนตรรกยะเมื่อทำได้เพื่อรักษาความแม่นยำ
- ใช้การแทนค่าเชิงสัญลักษณ์ให้มากที่สุดเพื่อลดการคำนวณแบบ RRA
- ผลลัพธ์คือระบบเครื่องคิดเลขที่สมบูรณ์แบบ ซึ่งสร้างสมดุลระหว่างความเร็วและความแม่นยำได้
บทสรุป
- เครื่องคิดเลข Android ที่ Boehm และทีมของเขาสร้างขึ้นไม่ใช่โปรแกรมธรรมดา
- มันใช้อัลกอริทึมที่รวดเร็วและมีประสิทธิภาพ พร้อมให้ผลลัพธ์ที่ถูกต้อง
- มันไม่ใช่ "ก็แค่แอปเครื่องคิดเลข" แต่เป็นระบบที่ประณีตลึกซึ้งในเชิงคณิตศาสตร์
"ครั้งหน้าที่คุณใช้เครื่องคิดเลข Android ลองนึกถึงความพยายามนี้ดู!"
12 ความคิดเห็น
พูดนอกเรื่องนิดหนึ่ง แต่ก็น่าสนใจที่ AI อย่าง neo แปลออกมาเป็น "ก็ทำได้กันทุกคนไม่ใช่เหรอ" ต้นฉบับคือ "Anyone could make that" ซึ่งจริง ๆ ไม่ได้มีน้ำเสียงขี้เล่นแบบนั้นนะ 555 แต่กลับเข้ากันได้ดีมากเลย
ตอนที่ผมยังเป็นนักศึกษาปริญญาตรี มีวิชาหนึ่งที่ให้บัดกรีบอร์ด 8086 ด้วยมือเอง แล้วต่อแป้นตัวเลขกับ Text LCD จากนั้นก็ต้องทำเครื่องคิดเลขด้วยภาษาแอสเซมบลีของ 8086 ขึ้นมาเครื่องหนึ่ง (ที่ทำได้แค่สี่การคำนวณพื้นฐาน)
ผมทำบอร์ดเสร็จ ต่อคีย์แพดกับ LCD จนใช้งานได้แล้ว แต่ทำเครื่องคิดเลขไม่สำเร็จ
ตอนนั้นผมเลยคิดว่าตัวเองคงไม่มีพรสวรรค์ด้านซอฟต์แวร์ ก็เลยไปหางานเป็นวิศวกรฮาร์ดแวร์ แต่สุดท้ายก็กลายมาเป็นนักพัฒนาซอฟต์แวร์อยู่ดี
เครื่องคิดเลขนี่ ยากจริง ๆ ครับ
น่าจะเป็น
거자나->거잖아ครับ/ค่ะ 😃จะปรับเลขทศนิยมลอยตัวยุ่งหัวเอาเรื่องเลยนะ? 555555
พอพูดถึงแอปเครื่องคิดเลข ผมก็นึกถึงเครื่องคิดเลขพื้นฐานของ Windows เลยครับ ถ้าคำนวณ 2+2*2 จะได้ 8 ไม่ใช่ 6 เหมือนเขาตั้งใจทำให้เป็นแบบนี้ แต่ผมก็ไม่เข้าใจเอาเสียเลย เพราะเมื่อก่อนผมเคยคำนวณปริมาณแอลกอฮอล์ในค็อกเทล แล้วผลออกมาว่าปริมาณแอลกอฮอล์มากกว่าปริมาณเครื่องดื่มทั้งหมดเสียอีก เลยตกใจมาก
แอปเครื่องคิดเลขเหรอ? ใคร ๆ ก็ทำได้ไม่ใช่เหรอ?
มันเป็นการทำงานแบบเครื่องคิดเลขอิเล็กทรอนิกส์ทั่วไปที่ทุกครั้งที่กดตัวดำเนินการ ระบบจะคำนวณสมการก่อนหน้าทันที หรือว่าคุณเคยใช้แต่เครื่องคิดเลขวิทยาศาสตร์?
เห็นด้วยอย่างยิ่งครับ เริ่มทำเครื่องคิดเลขเพราะคิดว่าดีตรงไม่ต้องมีเซิร์ฟเวอร์ แต่กลับต้องเหนื่อยมากกับการไล่แก้ข้อผิดพลาดในการคำนวณและบั๊กที่โผล่ออกมาไม่หยุด
ภาพรวมการติดตั้งใช้งานในซอร์สโค้ด
คำอธิบายตรรกะการคำนวณของเครื่องคิดเลขในซอร์สโค้ด
โค้ดสำหรับจัดการจำนวนเต็ม
โค้ดสำหรับจัดการจำนวนจริง
"แอปเครื่องคิดเลข? ใคร ๆ ก็ทำได้อยู่แล้วไม่ใช่เหรอ" → จริง ๆ แล้วไม่ใช่
ดูเหมือนว่าจะเอาไปประยุกต์ใช้ต่อได้อีกไม่รู้จบเลยนะ 555
"Python? ง่ายจะตายไม่ใช่เหรอ" → จริง ๆ แล้วไม่ใช่
ผมก็คิดเหมือนกันตอนดูอยู่ครับ 555
"JavaScript เหรอ? ชิลมาก" → ที่จริงไม่ใช่
"(10^100)+1−(10^100)"
โอ้ จริงด้วย เครื่องคิดเลขบน iPhone แสดงเป็น 0 ส่วนเครื่องคิดเลขบน Android แสดงเป็น 1
แต่พอค้นหาใน Google กลับแสดงเป็น 0 แฮะ...
ความคิดเห็นจาก Hacker News