ตัวเลขทศนิยมสามารถเปรียบเทียบได้เหมือนจำนวนเต็ม แต่มีข้อแม้

ทีมชุมชน BigGo
ตัวเลขทศนิยมสามารถเปรียบเทียบได้เหมือนจำนวนเต็ม แต่มีข้อแม้

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

เทคนิคการเปรียบเทียบแบบจำนวนเต็ม

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

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

รูปแบบ IEEE 754 Single Precision (32-bit)

  • Sign bit: 1 บิต (0 = บวก, 1 = ลบ)
  • Exponent: 8 บิต (มีการ bias ด้วย 127)
  • Significand: 23 บิต (มี implicit leading 1)
  • รวม: 32 บิต

ข้อจำกัดที่คุณต้องรู้

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

ตัวเลขทศนิยมมาตรฐานใช้การแทนค่าแบบ sign-magnitude ในขณะที่จำนวนเต็มที่มีเครื่องหมายในปัจจุบันใช้ 2s-complement ในตัวเลขลบ การเปรียบเทียบจะกลับกันระหว่างการเข้ารหัสทั้งสองแบบนี้

ตัวเลขทศนิยมใช้การแทนค่าแบบ sign-magnitude ซึ่งเครื่องหมายถูกเก็บแยกจากขนาด จำนวนเต็มที่มีเครื่องหมายสมัยใหม่ใช้การแทนค่าแบบ two's complement ความแตกต่างนี้หมายความว่าสำหรับตัวเลขลบ ลำดับการเปรียบเทียบจะกลับกันระหว่างรูปแบบทั้งสอง

ข้อจำกัดของการเปรียบเทียบ Floating Point

  • ✅ ใช้ได้กับ: ตัวเลขบวก, การเปรียบเทียบระหว่างบวกกับลบ
  • ❌ ใช้ไม่ได้กับ: การเปรียบเทียบตัวเลขลบ, ค่า NaN, อนันต์, ศูนย์ลบ
  • สาเหตุหลัก: Sign-magnitude (floats) เทียบกับ Two's complement (integers)

ทางเลือกสมัยใหม่และผลกระทบต่อการพัฒนาเกม

การอภิปรายยังได้สัมผัสถึงรูปแบบตัวเลขใหม่ๆ เช่น Posits ซึ่งใช้ two's complement ตลอดทั้งหมดและขจัดกรณีขอบเขตเหล่านี้หลายอย่าง ต่างจากตัวเลขทศนิยมแบบดั้งเดิม Posits สามารถเรียงลำดับได้เหมือนจำนวนเต็มสำหรับค่าทั้งหมด ทำให้คาดเดาได้มากขึ้นสำหรับนักพัฒนา

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

บทสรุป

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

อ้างอิง: Float Value: 1532.625