59 คะแนน โดย GN⁺ 2025-02-17 | 12 ความคิดเห็น | แชร์ทาง WhatsApp

"แอปเครื่องคิดเลข? ใครๆ ก็ทำได้ไม่ใช่เหรอ" → ที่จริงไม่ใช่เลย

  • เครื่องคิดเลขต้องแสดงผลลัพธ์ของนิพจน์ทางคณิตศาสตร์ให้ถูกต้อง และเรื่องนี้ยากกว่าที่คิดมาก
  • ในเครื่องคิดเลขของ 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 ความคิดเห็น

 
street62 2025-02-20

พูดนอกเรื่องนิดหนึ่ง แต่ก็น่าสนใจที่ AI อย่าง neo แปลออกมาเป็น "ก็ทำได้กันทุกคนไม่ใช่เหรอ" ต้นฉบับคือ "Anyone could make that" ซึ่งจริง ๆ ไม่ได้มีน้ำเสียงขี้เล่นแบบนั้นนะ 555 แต่กลับเข้ากันได้ดีมากเลย

 
gurugio 2025-02-19

ตอนที่ผมยังเป็นนักศึกษาปริญญาตรี มีวิชาหนึ่งที่ให้บัดกรีบอร์ด 8086 ด้วยมือเอง แล้วต่อแป้นตัวเลขกับ Text LCD จากนั้นก็ต้องทำเครื่องคิดเลขด้วยภาษาแอสเซมบลีของ 8086 ขึ้นมาเครื่องหนึ่ง (ที่ทำได้แค่สี่การคำนวณพื้นฐาน)
ผมทำบอร์ดเสร็จ ต่อคีย์แพดกับ LCD จนใช้งานได้แล้ว แต่ทำเครื่องคิดเลขไม่สำเร็จ
ตอนนั้นผมเลยคิดว่าตัวเองคงไม่มีพรสวรรค์ด้านซอฟต์แวร์ ก็เลยไปหางานเป็นวิศวกรฮาร์ดแวร์ แต่สุดท้ายก็กลายมาเป็นนักพัฒนาซอฟต์แวร์อยู่ดี
เครื่องคิดเลขนี่ ยากจริง ๆ ครับ

 
yunsub2 2025-02-19

น่าจะเป็น 거자나 -> 거잖아 ครับ/ค่ะ 😃

 
carnoxen 2025-02-18

จะปรับเลขทศนิยมลอยตัวยุ่งหัวเอาเรื่องเลยนะ? 555555

 
tribela 2025-02-18

พอพูดถึงแอปเครื่องคิดเลข ผมก็นึกถึงเครื่องคิดเลขพื้นฐานของ Windows เลยครับ ถ้าคำนวณ 2+2*2 จะได้ 8 ไม่ใช่ 6 เหมือนเขาตั้งใจทำให้เป็นแบบนี้ แต่ผมก็ไม่เข้าใจเอาเสียเลย เพราะเมื่อก่อนผมเคยคำนวณปริมาณแอลกอฮอล์ในค็อกเทล แล้วผลออกมาว่าปริมาณแอลกอฮอล์มากกว่าปริมาณเครื่องดื่มทั้งหมดเสียอีก เลยตกใจมาก

 
khrad 2025-02-19

แอปเครื่องคิดเลขเหรอ? ใคร ๆ ก็ทำได้ไม่ใช่เหรอ?

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

 
ned0909 2025-02-18

เห็นด้วยอย่างยิ่งครับ เริ่มทำเครื่องคิดเลขเพราะคิดว่าดีตรงไม่ต้องมีเซิร์ฟเวอร์ แต่กลับต้องเหนื่อยมากกับการไล่แก้ข้อผิดพลาดในการคำนวณและบั๊กที่โผล่ออกมาไม่หยุด

 
aer0700 2025-02-17

"แอปเครื่องคิดเลข? ใคร ๆ ก็ทำได้อยู่แล้วไม่ใช่เหรอ" → จริง ๆ แล้วไม่ใช่
ดูเหมือนว่าจะเอาไปประยุกต์ใช้ต่อได้อีกไม่รู้จบเลยนะ 555

"Python? ง่ายจะตายไม่ใช่เหรอ" → จริง ๆ แล้วไม่ใช่

 
tsboard 2025-02-17

ผมก็คิดเหมือนกันตอนดูอยู่ครับ 555

"JavaScript เหรอ? ชิลมาก" → ที่จริงไม่ใช่

 
joyfui 2025-02-17

"(10^100)+1−(10^100)"
โอ้ จริงด้วย เครื่องคิดเลขบน iPhone แสดงเป็น 0 ส่วนเครื่องคิดเลขบน Android แสดงเป็น 1
แต่พอค้นหาใน Google กลับแสดงเป็น 0 แฮะ...

 
GN⁺ 2025-02-17
ความคิดเห็นจาก Hacker News
  • เป็นเรื่องที่น่าสนใจ วิธีที่ทรงพลังกว่าในการแทนตัวเลขคือการใช้เศษส่วนต่อเนื่อง ซึ่งสามารถแทนจำนวนจริงและจำนวนตรรกยะได้อย่างมีประสิทธิภาพ
    • เกร็ดน่าสนใจคือ ตามหนังสือเรียนคณิตศาสตร์ที่ไม่ได้เก่ามาก มีความเป็นไปได้สูงว่าอัลกอริทึมสำหรับการบวก/คูณของเศษส่วนต่อเนื่องอาจไม่มีอยู่จริง แต่ในปี 1972 Bill Gosper ได้พิสูจน์ว่าเศษส่วนต่อเนื่องเหมาะกับการคำนวณเลขคณิตอย่างสมบูรณ์แบบ
    • ฉันกำลังพัฒนาไลบรารี Python ชื่อ reals อยู่ ไลบรารีนี้ถูกออกแบบมาเพื่อใช้แทนชนิด Decimal หรือ Fraction โดยจัดการเศษส่วนต่อเนื่องด้วยเทคนิคของ Bill Gosper
  • น่าเสียดายที่ลิงก์ถูกย่อจนกดไม่ได้ นี่คือลิงก์จริงไปยังบทความ
  • แค่อ่านชื่อเรื่องก็หลุดขำแล้ว IEEE 754 แย่มาก แต่ก็ยังดีกว่าทางเลือกอื่นทั้งหมด พอเห็นตัวอย่างก็คิดทันทีว่าน่าจะเป็น Kahan summation หรือไม่ก็ระบบพีชคณิตเชิงคอมพิวเตอร์เต็มรูปแบบ ไม่เคยได้ยิน Recursive Real Arithmetic มาก่อน
    • ทำให้ได้มุมมองเกี่ยวกับหนึ่งในฮีโร่ยุคแรกของ C++ และเตือนใจว่าสิ่งที่ดูเรียบง่ายนั้นลึกซึ้งได้แค่ไหน
  • ค่าโดยสารรถไฟใต้ดิน NYC คือ $2.90 ตอนใช้ PCalc บน iOS คำนวณยอดคงเหลือใน MetroCard ที่เหลือ กลับได้ค่า -8.881784197E-16 แทนที่จะเป็น 0 เรื่องแบบนี้ไม่เกิดเวลาฉันใช้เครื่องคิดเลขของ Apple
    • ฉันติดต่อผู้พัฒนาแล้วได้รับคำตอบว่า Apple ใช้ไลบรารีคณิตศาสตร์ของตัวเอง และพวกเขาจำเป็นต้องหาไลบรารีอื่นมาแทน
  • แทบไม่มีใครสร้างแอปเครื่องคิดเลขแบบสมบูรณ์จริง ๆ หมายถึงเครื่องคิดเลขเต็มรูปแบบอย่าง TI-89
    • ฉันใช้โปรแกรมจำลองเครื่องคิดเลข TI-89 บน Android อยู่ มันมีฟังก์ชันไม่ถึงครึ่งของแอป Android ทั่วไป และยังทำงานได้ไม่ค่อยดี
  • ข้อเสียของการเปลี่ยนไปใช้ RRA ไม่ได้มีแค่ประสบการณ์ผู้ใช้เท่านั้น เมื่อผลลัพธ์เป็น 0.0000000... เครื่องคิดเลขจะไม่สามารถตัดสินใจได้ว่าสามารถคำนวณค่ากลับกันของจำนวนนั้นได้หรือไม่
    • ตัวอย่างเช่น 1/(atan(1/5)-atan(1/239)-pi/4) จะแสดงว่า "คำนวณไม่ได้" และแม้จะลอง 1/(atan(1/5)-atan(1/239)-pi/4+10^(-100000)) ก็ยังแสดงว่า "คำนวณไม่ได้" อยู่ดี
  • แทบทุกจำนวนไม่สามารถแทนได้ด้วย IEEE floating point และมีโอกาสเกือบ 100% ที่จำนวนสุ่มหนึ่งจำนวนจะอธิบายได้ไม่ได้ในเชิงทฤษฎี
    • ปัญหาบางอย่างหลีกเลี่ยงได้ด้วยการใช้ bignums ความวิตกเชิงภาวะตัวตนชั่วขณะจึงคลี่คลายลง
  • มีใครรู้บ้างว่าเครื่องคิดเลข TI ระดับสูงอย่าง TI-92 ใช้ระบบนี้หรือเปล่า? มันมีโหมด "จำนวนตรรกยะ" และอาจใช้ RRA ก็ได้
  • วิธีใช้ "recursive real arithmetic" (RRA) ทำให้นึกถึงบทสนทนาดี ๆ กับ Conal Elliot เกี่ยวกับการเปลี่ยนจากการแทนสิ่งต่าง ๆ แบบไม่ต่อเนื่องไปเป็นแบบต่อเนื่อง
    • ตัวอย่างเช่น เมื่อก่อนเราแทนฟอนต์เป็นบล็อกพิกเซล แต่ตอนนี้มองเป็นเส้น/เวกเตอร์ วิทยาการคอมพิวเตอร์ไม่ควรเป็นแค่การเรียนรู้เครื่องมือเชิงพาณิชย์ล่าสุดเท่านั้น แต่ควรเป็นการแสวงหาความจริงด้วย
  • ฉันเคยลองเล่นกับซอร์สโค้ดเครื่องคิดเลขของ Android Open Source Project แล้ว Google ย้ายมันไปไว้ใน Google Play Services แต่ซอร์สเก่ายังหาใช้ได้อยู่
    • มันแก้ปัญหาจริงได้บางอย่าง และหวังว่าจะใช้ได้จากในไลบรารี มีการพูดถึงไลบรารีบางตัวไว้ในบทความก่อนหน้า