7 มิ.ย. 2023 เวลา 04:31 • วิทยาศาสตร์ & เทคโนโลยี

วิธีการแปลงค่าเลขทศนิยม Floating Point เป็น Binary

บทนำ
ภาษา C เราอาจจะไม่เห็นความแตกต่างกันระหว่างเลขจำนวนเต็มและเลขทศนิยมมากนัก
สำหรับระบบ Embedded System (Microcontroller) ในหลายกรณี จะต้องคำนวนค่าต่างๆ ด้วยระบบตัวเลขทศนิยม เช่น การคำนวนหาค่าแรงดันจากโมดูล Analog to Digital Converter หรือการคุม PWM เป็นต้น
หาก การเขียนโปรแกรมด้วยภาษา C เราอาจจะไม่เห็นความแตกต่างกันระหว่างเลขจำนวนเต็มและเลขทศนิยมมากนัก โดยสามารถประกาศชนิดตัวแปรเป็น float, double เมื่อต้องการใช้เลขทศนิยม แต่ระบบ Microcontroller มีข้อจำกัดเล็กน้อยซึ่งแตกต่างจากคอมพิวเตอร์ส่วนบุคคลนั่นคือ “ปริมาณหน่วยความจำ” โดยจะคำนวนผ่านตัวแปร Accumulator (ขึ้นกับชนิด Microcontroller) หรือ เก็บใน Ram หรือ Register ต่าง ๆ
การใช้งานเลขทศนิยมใน ไมโครคอนโทรลเลอร์ถูกกำกับด้วย Data Type
เช่น
Float มีความยาว 32 Bit
Double มีความยาว 64 Bit เป็นต้น
ในคอมไพล์เลอร์บางชนิด เช่น XC8 สามารถเลือกคอมไพล์ตัวแปร Float โดยกำหนดความยาวเพียง 24 Bit เท่านั้น นั่นคือหากประกาศตัวแปร float 1 ตัว จะสามารถลดขนาดหน่วยความจำได้ 1 byte หากประกาศตัวแปรอาเรย์ float ความยาว 10 จะใช้หน่วยความจำเพียง 240 bytes ลดลงจากตัวแปร float 32 bits ถึง 32x10–24x10 = 80 bit ~ 10 bytes
ตัวเลข 10 bytes ไม่ได้มีปริมาณเยอะมากนัก หากใช้ใน Microcontroller รุ่นใหม่ๆ แต่ใน Microcontroller รุ่นเล็กและรุ่นเก่าก็เป็นปัญหาพอสมควร
ในคอมไพล์เลอร์ภาษา C สามารถใช้ union และ struct สำหรับช่วยแปลงตัวเลขทศนิยมได้ จะกล่าวในบทถัดไป
ในบทความนี้จะกล่าวถึงการแปลงค่าตัวเลข float เป็น binary
วิธี
ตัวเลขทศนิยมที่ต้องการแปลงค่า เช่น
ตัวเลขที่ต้องการแปลงค่า 123.456
2. แบ่งตัวเลขออกเป็นจำนวนเต็มและจำนวนทศนิยม
จำนวนเต็ม: 123
ทศนิยม: 0.456
ขั้นตอนนี้ หากเลขจำนวนเต็มเป็นจำนวนเต็มลบ บิตที่ 32 จะต้องเป็น 1 และหากเป็นจำนวนเต็มบวกจะเป็น 0
3. แปลงเลขจำนวนเต็มและเศษส่วนให้อยู่ในรูป Binary โดย ตัวเลขที่มากกว่า 1 ค่าประจำหลักจะเพิ่มครั้งละ 2 เท่า จากขวาไปซ้าย ส่วน ตัวเลขที่น้อยกว่า 1 ค่าประจำหลักจะลดลงครั้งละ 2 เท่าเช่นกัน
123 =
: 0x128 + 1x64 + 1x32 + 1x16 + 1x8 + 0x4 + 1x2 + 1x1
= 0 1 1 1 _ 1 0 1 1 #
0.456 =
: 0x1/2 + 1x1/4 + 1x1/8 + 1x1/16 + 0x1/32 + 1x1/64 + 0x1/32 ……..
(คิดเป็นตัวเลข Binary ได้ 0.01110100101111000110101001111110…)(note 1)
4. นำตัวเลขมาเรียงต่อกันในรูปแบบไบนารี่ จะได้
0111 1011 . 01110100101111000110101001111110
5. ตัวเลขข้างบนในข้อ 4 จะต้องเขียนให้อยู่ในรูป 1xb^e
เมื่อเขียนตัวเลขไบนารี่อยู่ในรูป 1x b^e จำนวนครั้งที่เลื่อนทศนิยมคือการคูณขึ้นหรือหารลงทีละสองแล้วแต่จะเลื่อนไปทางไหน
6. จากรูปข้างบน ตัวเลขในวงน้ำเงิน คือเลข 1 ในหลักหน่วย เอาเลข 1 ในหลักหน่วยไปคูณกับค่าอะไรก็จะได้ค่านั้น ส่วน เลข 6 ของ 2⁶ นั้น จะเอาไปคำนวนโดยจากมาตรฐานของ IEEE754 กำหนดให้ ความยาวของ Exponent มีความยาว 8 bit ดังนั้นจะต้องใช้ฐาน 2^(8–1) — 1 = 127 ฐานของเลขทศนิยมนี้คือ 127 บวกกับจำนวนครั้งที่เลข 2 เลื่อนไปทางซ้าย แล้วไม่ต้องเขียนตัวเลขในรูป x2⁶ อีกต่อไป
127 + 6 = 133 : 10000101
01.11 1011 01110100101111000110101001111110 x 2⁶
= 10000101 x 01.11 1011 0111 0100 1011 1100 0110 1010 0111 1110
= 10000101 ____11 1011 0111 0100 1011 1100 0110 1010 0111 1110
ตัดส่วนเกิน 32 bit ออกโดยไม่ปัดค่า
= 0100 0010 1111 0110 1110 1001 0111 1000 ###### คือคำตอบ
ตรวจสอบกับเวป https://www.h-schmidt.net/FloatConverter/IEEE754.html พิมพ์ไบนารีลงไปในช่อง Bianry Representation แล้วกด Enter
เห็นว่าค่า Decimal เป็น 123.455993652 นั่นคือเราจะเป็นต้องปัดค่าในบิตที่ 0 ให้เป็น 1 เนื่องจากยังเหลือเศษเหลือพอจะปัดค่าได้ (ตรวจสอบจาก Binary ได้) ต้องไม่ลืมใส่บิตเครื่องหมาย +/-
สรุป
แยกเลขจำนวนเต็ม แยกทศนิยม
หา Binary ทั้งจำนวนเต็ม และ ทศนิยม
เลื่อนทศนิยมไบนารี่ให้อยู่ในรูป 1.bbbbb x 2^e
หากเลื่อนทศนิยมไปทางซ้าย เอาจำนวนครั้งที่เลื่อนไปบวกกับ 127 หากเลื่อนไปทางขวาเอาไปลบกับ 127 แล้วแปลงผลลัพธ์เป็นไบนารี
ผลลัพธ์จากข้อ 4 เอาต้องไม่เกิน 8 bit (แน่อยู่แล้ว มันคำนวนจากฐาน 127) เอามาต่อหน้าไบนารี่หลังทศนิยมได้เลย
ตัดไบนารี่ให้เหลือ 31 บิต บิตบนสุดจะเป็นตัวกำหนดเครื่องหมาย +/-
Note
หากเขียน Excel ให้แปลงเลขทศนิยมเป็นไบนารี่ได้จะสะดวกกว่าคำนวนมือ โดยใช้คำสั่ง if เท่านั้น
โฆษณา