irpg Community

Full Version: วิธีถอดรหัสตัวแปรทศนิยม (Float) ขนาด 32 bit
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Floating-point หรือ Float เป็นตัวแปรที่เราคงเคยผ่านตากันมาบ้าง เวลาเขียนโปรแกรมในหลายภาษา
เคยสงสัยไหมว่ามันเก็บข้อมูลอย่างไร เราจะไปหาคำตอบกัน

[Image: xoWb3P5.jpg]
ตามที่กำหนดไว้ใน IEEE-754 ตัวแปรทศนิยม Floating Point ขนาด 32 บิต มีลักษณะเป็นดังภาพด้านบน

เราสามารถแบ่งข้อมูลออกเป็น 3 ส่วน
1. Sign เก็บค่าเครื่องหมาย +,- มีขนาด 1 บิต (ถ้าลบ จะเป็น 1 ส่วนบวกจะเป็น 0)
2. (Biased) Exponent เก็บค่าเลขชี้กำลัง ซึ่งจะนำมาใช้คำนวณค่าทศนิยม ขนาด 8 บิต

3. Mantissa เลขนัยสำคัญ เรียกอีกชื่อนึงว่า significant ขนาด 23 บิต

ในการคำนวณหาค่าทศนิยม จะใช้สมการดังนี้
[Image: 9pF2Iek.png]
หมายเหตุ: เราจะยังไม่สนใจกรณีที่ค่าเป็นอนันต์ Infinity (ทั้งบวกและลบ) กับกรณีที่ค่าเป็น NaNs ก่อน

127 ก็คือ bias หรือ offset ที่จะนำมาลบ เพื่อหาค่าจริงของเลขชี้กำลัง
2 ยกกำลัง 23 จะอ้างอิงถึง 23 บิต significant ซึ่งเป็นเศษส่วนฐานสอง (base-2 fraction) แต่ละบิตจะแทนเศษส่วนของฐานสอง ดังภาพด้านล่าง

[Image: svJsJpM.png]

สำหรับโค้ดในที่นี้เขียนด้วยภาษา C/C++ แต่ท่านสามารถนำไปประยุกต์ใช้ในภาษาอื่น ได้เช่นกัน

[Image: eSBZYIB.png]
https://i.imgur.com/eSBZYIB.png

อธิบายขั้นตอนแบบสั้น
1.แปลง float ให้อยู่ในรูปที่เราสามารถเข้าถึงข้อมูล binary ได้ ในที่นี้ใช้การ cast ให้เป็น pointer ของ unsigned integer ซึ่งมีขนาด 32 บิตเท่ากัน
2.แกะข้อมูล binary ทั้งหมดออกมา ในที่นี้ใช้วิธีการ shift เลื่อนแต่ละบิตไปจนสุดด้านซ้าย (least significant bit) จากนั้นใช้ AND operator กรองเอาเฉพาะบิตที่ต้องการ
3.คำนวณค่าตามสมการด้านบนที่ได้กล่าวไว้แล้ว

ค่าของตัวแปร result คือผลลัพธ์จากการคำนวณ ซึ่งจะมีค่าเท่ากับตัวแปร float ที่เราประกาศไว้ในตอนแรกทุกประการ (ยกเว้นกรณี infinity กับ NaNs ไม่ได้มีการตรวจสอบ)