Floating Point Representation

By Unknown | วันอังคาร, กุมภาพันธ์ 04, 2557

Floating Point เป็นรูปแบบในการจัดเก็บข้อมูลที่เป็นจำนวนจริงลงในหน่วยความจำที่เก็บข้อมูลเป็นเลขฐานสอง โดยใช้มาตรฐาน IEE754 ซึ่งจะต้องเปลี่ยนจำนวนจริงใด ๆ ให้เป็นเลขฐานสองก่อนแล้วจึงทำการ Normalize จุดทศนิยมให้อยู่ในรูปของ significant notation, bias ตัวยกกำลังด้วย 127  แล้วทำการเก็บข้อมูลลงไป


Bit mapping ของ floating point

สมมุติว่าเราต้องการหาว่า 130.625 นั่นถูกเก็บอยู่ในหน่วยความจำยังไง เราสามารถทำได้ดังนี้


How to represent real number as binary string
  1. แปลงเป็นเลขฐานสอง

    การแปลงเลข 130.625 เป็นเลขฐานสองนั้น เพื่อความง่ายและไม่สับสนเราจะแบ่งเลขออกเป็นสองส่วนคือ ส่วนหน้าจุดทศนิยมและหลังจุดทศนิม ขั้นแรกให้เราแปลง 130 เป็นเลขฐานสองก่อน เราจะได้เป็น 10000010, หลังจากนั้นกลับที่เลขหลังทศนิยมทำการแปลงเป็นเลขฐานสองก็จะได้ 10 (การแปลงเลขทศนิยมเป็นเลขฐานสอง) ดังนั้นเราก็จะได้ 130.625 ในเลขฐานสองเป็น 10000010.101

  2. Normalize ให้อยู่ในรูปของ significant notation

    เมื่อเราได้เลขฐานสองของจำนวนจริงมาแล้วให้ทำการเลือนจุดทศนิยมไปให้ 1 อยู่หน้าจุดทศนิยม เช่น 0.00001010011 จะต้องเลื่อนทศนิยมไปทางขวา 5 ตำแหน่ง หลังจากเลื่อนแล้วก็ได้จะเป็น 1.010011x2E-5 จากตัวอย่างของเรา 10000010.101 จะต้องเลื่อนไปทางซ้าย 7 ตำแหน่ง ทำให้หลังจากเรา normalize แล้วจะได้ 1.0000010101x2E7

  3. Bias เลขยกกำลังด้วย 127

    เนื่องจากเลขยกกำลังจะถูกเก็บด้วยความยาว 8 บิต ซึ่งทำให้สามารถเก็บค่าได้ตั้งแต่ 0-255 แต่เนื่องจากในความเป็นจริงเรา เรายังต้องการใช้เลขที่เป็นลบอยู่ ดังนั้นการ bias ตัวยกกำลังด้วย 127 (ครึ่งนึงของ 255) ทำให้เราสามารถเก็บค่าได้ตั้งแต่ -127 ถึง 128 (Two's Complement Representation) ดังนั้นให้เราเอาเลขยกกำลังมาบวกด้วย 127 ก็จะได้ 1.0000010101x2E134 แล้วทำการแปลง 134เป็นเลขฐานสองต่ออีกหน่อยทำให้เราได้ 1.0000010101x2E10000110

  4. เก็บลงหน่วยความจำ

    จากเลขที่เราแปลงมาได้เป็น 1.0000010101x2E10000110 เป็นค่าบวก แสดงว่าบิตแรกเป็น 0 ต่อจากนั้น 8 บิตคือเลขยกกำลัง ในที่นี้ก็คือ 10000110 ส่วนบิตที่เหลือคือ 0000010101 (ที่ไม่เอา 1 มาเก็บเพราะจะเห็นได้ว่าเมื่อเราเขียนจำนวนจริงให้อยู่ในรูปของ significant notation แล้วเลขข้างหน้าจะเป็น 1 เสมอ ทำให้ประหยัดพื้นที่ไปอีก 1 บิตในการเก็บข้อมูล)

ผมลองเขียนโปรแกรมให้ dump ค่าออกมาจาก memory สามารถศึกษาเพิ่มเติมได้ที่นี้ : C# , Java

การแปลงเลขทศนิยมให้อยู่ในรูปของเลขฐานสอง

Float number converting to bin

สำหรับการแปลงเลขทศนิยมให้อยู่ในรูปฐานสองนั้นจะทำไม่เหมือนกับการแปลงจำนวนเต็มให้อยู่ในรูปแบบฐานสอง ที่เราใช้วิธีการหาร หรือการนับหน่วย แต่จะใช้วิธีการคูณด้วยเลข 2 (เพราะเราต้องการแปลงเป็นเลขฐานสอง) กับเลขทศนิยมจนหว่าจะมีค่าเป็น 1.00 ยกตัวอย่างอย่างเช่น เลข 0.625 (จะมีค่าเท่ากับ 0.101 => (2E-1)+(2E-3)) ให้เรานับเฉพาะทศนิยมมาคูณสองไปเรื่อย ๆ เมื่อคูรเสร็จในขั้นใด ๆ ให้เอาผลคูณในขั้นนั้น ๆ มาคูณกับสองต่อ ทำไปเรื่อย ๆ จนกว่าผลคูณจะเป็น 1.00 หลังจากนั้นให้สังเกตที่ผลคูณที่เราคูณไว้ ไล่จากบนมาลง ผลคูณในลำดับที่เท่าไหร่มีค่ามากกว่าหรือเท่ากับ 1 แสดงว่าจะจะได้เลข 1 ในหลักนั้น ในทางตรงกันข้ามจะได้เลข 0 ในหลักนั้นของเลขฐานสอง (อาจจะงง ลองดูภาพประกอบ)

Float number converting to bin

แสดงความคิดเห็น