IEEE 754 Float Explorer: ดูบิตเบื้องหลังจำนวน floating-point ทุกตัว
แยกจำนวนใด ๆ ออกเป็นบิต sign, exponent และ mantissa แบบ binary32/binary64 คลิกสลับบิตทีละบิตพร้อมเห็นค่าเปลี่ยน ดูค่า decimal เท่าตัวและวิเคราะห์ rounding error ด้วย IEEE 754 Float Explorer ฟรี ทำงานในเบราว์เซอร์ 100%
Table of Contents
IEEE 754 Float Explorer: ดูบิตเบื้องหลังจำนวน floating-point ทุกตัว
ลองพิมพ์ 0.1 + 0.2 ลงใน console ของ JavaScript แล้วคุณจะได้ผลลัพธ์เป็น 0.30000000000000004 ปริศนานี้เคยตามหลอกหลอนนักพัฒนาเว็บมาทุกคน แต่ไม่ค่อยมีใครได้แอบดูบิตที่ซ่อนอยู่เบื้องหลังมันเลย IEEE 754 Float Explorer ช่วยเรื่องนี้ได้ในไม่กี่วินาที: ใส่ตัวเลขอะไรก็ได้ แล้วเครื่องมือจะแยกมันออกเป็นบิต sign, exponent และ mantissa ที่โปรเซสเซอร์ของคุณเก็บจริง
พูดให้ชัดก่อนว่า 0.1 + 0.2 !== 0.3 ไม่ใช่บั๊กของ JavaScript — แต่เป็น IEEE 754 ทำงานตรงตามบิตที่กำหนดไว้อย่างเป๊ะ และเครื่องมือนี้จะพาคุณไปเห็นบิตเหล่านั้น ทุกค่า floating-point ก็คือวิธีเขียนแบบ scientific notation จิ๋ว ๆ ที่ถูกอัดลงใน 32 หรือ 64 บิต: บิต sign หนึ่งบิต, ช่อง exponent แบบ biased และส่วนเศษที่เรียกว่า mantissa แทนที่จะท่องจำความเชื่อเรื่อง "float มันแปลก ๆ" คุณสามารถคลิกสลับบิตทีละบิตแล้วดูว่าค่าเปลี่ยนไปอย่างไร ซึ่งสอนเรื่องนี้ได้ดีกว่าแผนภาพนิ่ง ๆ เสมอ
เครื่องมือนี้ใช้งานได้จริง ไม่ใช่แค่ใช้เพื่อการเรียน มันพิมพ์ค่า decimal เท่าตัวที่ซ่อนอยู่หลังเลขสั้น ๆ ที่คุณพิมพ์ คำนวณ rounding error ให้เห็นชัด แสดง hex view พร้อมใช้กับ debugger และแยกค่า NaN กับ Infinity ได้ถูกต้อง ทุกอย่างทำงานแบบ client-side ล้วน จึงเร็ว เป็นส่วนตัว และฟรี
Why Use IEEE 754 Float Explorer?
- เห็นสิ่งที่เครื่องเห็น. เลข decimal ที่คุณพิมพ์แทบไม่เคยเป็นค่าที่ถูกเก็บจริง explorer จะวางบิตแพตเทิร์น binary32 หรือ binary64 ตัวจริงไว้ตรงหน้าคุณ
- อธิบาย rounding error ตั้งแต่ต้นทาง. การเทียบค่าที่ป้อนกับค่าเท่าตัวที่ถูกเก็บ เปลี่ยนคำว่า "ปัญหา precision คร่าว ๆ" ให้กลายเป็นตัวเลขที่วัดได้จริง
- เรียนรู้ผ่านการทดลอง. คลิกบิตไหนก็ได้แล้วค่าจะอัปเดตทันที ทำให้เรื่อง number representation เป็นสิ่งที่ลองเล่นได้ ไม่ใช่สิ่งที่ต้องท่อง
- รองรับสองฟอร์แมตหลัก. สลับระหว่าง binary32 (1 + 8 + 23 บิต) กับ binary64 (1 + 11 + 52 บิต) เพื่อดูว่าฟอร์แมต double ให้ความละเอียดเพิ่มขึ้นเท่าไร
- จัดการเคสพิเศษอย่างตรงไปตรงมา. NaN, Infinity, zero และ denormals จะแสดงบิตแพตเทิร์นจริง ไม่ใช่แค่ข้อความ error กำกวม ๆ
- ไม่ต้องตั้งค่าอะไรเลย. เป็นเครื่องมือฟรี ทำงาน client-side 100% ไม่ต้องสมัคร ไม่มีการอัปโหลด ใช้ได้กับทุกอุปกรณ์ที่มีเบราว์เซอร์
Key Features
| Feature | What it does |
|---|---|
| Bit decomposition | แยกตัวเลขเป็นช่อง sign, exponent และ mantissa ทั้งแบบ binary32 และ binary64 |
| Live bit toggles | คลิกบิตใดก็ได้แล้วค่าตัวเลขอัปเดตทันที |
| Exact decimal readout | พิมพ์ค่า decimal เท่าตัวของบิตที่เก็บออกมาเต็ม ๆ ยาวแค่ไหนก็ได้ |
| Rounding error analysis | วัดช่องว่างระหว่างค่าที่คุณป้อนกับสิ่งที่ฟอร์แมตเก็บได้จริง |
| Hex view | แสดงคำ IEEE 754 ดิบ ๆ เป็นเลขฐานสิบหก พร้อมใช้กับ debugger และ memory dump |
| Special value support | แยก NaN, Infinity, zero และ denormals ได้อย่างถูกต้อง |
| 100% client-side | ทุกการคำนวณเกิดขึ้นในเบราว์เซอร์ของคุณ ไม่มีข้อมูลอะไรถูกส่งออกไป |
มีสามจุดที่น่าสนใจเป็นพิเศษ ค่า decimal เท่าตัวนั้น "เท่าจริง" แบบไม่ตัดทอน — ถ้าป้อน 0.1 ในโหมด binary64 มันจะพิมพ์ 0.1000000000000000055511151231257827021181583404541015625 ไม่ใช่เลขสั้น ๆ แบบที่เราคุ้นเคย ส่วน bit toggles ใช้ได้สองทาง: สลับบิต exponent เพื่อกระโดดเป็นเท่าของสอง หรือสลับบิต mantissa ตัวท้าย ๆ เพื่อขยับค่าทีละหนึ่ง ULP และเพราะรับ input แบบ hexadecimal คุณจึงวาง memory word ดิบอย่าง 0x4048F5C3 ลงไปถอดรหัสได้ทันที
How to Use
- ใส่ตัวเลข. พิมพ์เลข decimal เช่น 0.1, 3.14 หรือ -273.15 หรือจะวาง bit pattern แบบ hex อย่าง 0x4048F5C3 เพื่อถอดไบต์ดิบจากหน่วยความจำหรือไฟล์ก็ได้
- อ่านบิตทั้งสามช่อง. แถบบิตจะแสดงบิต sign, ช่อง exponent และ mantissa โดยทุกบิตถูกวาดเป็นช่องสี่เหลี่ยมของตัวเอง เห็นคำ 32 หรือ 64 บิตเต็ม ๆ ในแวบเดียว
- สลับบิตแล้วดูค่า. คลิกช่องไหนก็ได้เพื่อพลิกบิต พลิกบิต sign ค่าจะกลางเครื่องหมาย พลิกบิต exponent ค่าจะถูกคูณด้วยกำลังสอง และพลิกบิต mantissa ความละเอียดจะเปลี่ยนอย่างละเอียดอ่อน
- เทียบ binary32 กับ binary64. สลับ precision แล้วใส่ตัวเลขเดิมทั้งสองโหมด เลข 3.14 ลงตัวสบาย ๆ ใน binary64 แต่กลายเป็นค่าอื่นที่มองเห็นได้ชัดใน binary32
- ดู rounding error. อ่านค่า decimal เท่าตัวและผลวิเคราะห์ rounding เพื่อเห็นว่าค่าที่เก็บไว้ห่างจากเลขที่คุณพิมพ์ออกไปแค่ไหนอย่างแม่นยำ
Sign, Exponent, Mantissa
IEEE 754 อัดทุกค่าที่เก็บได้ลงในสามช่องที่อยู่ภายใต้สูตรเดียวกัน:
value = (-1)^sign × 1.mantissa × 2^(exponent - 127) สำหรับ binary32 โดย binary64 จะเปลี่ยน bias จาก 127 เป็น 1023
เลข 1 นำหน้าที่ซ่อนไว้. เลขฐานสองแบบ normalized ขึ้นต้นด้วย "1." เสมอ ฟอร์แมตจึงไม่ต้องเก็บเลขนั้นเลย ช่อง mantissa เก็บเฉพาะเศษ แล้ว explorer จะใส่ 1 ที่ซ่อนไว้กลับเข้าไปตอนสร้างค่าใหม่ — นั่นคือเหตุผลที่ mantissa 23 บิตให้ความละเอียดจริง 24 บิต และเศษ 52 บิตใน binary64 ให้ความละเอียด 53 บิต
biased exponent. ช่อง exponent เก็บเลขชี้กำลังจริงบวกกับ bias (127 หรือ 1023) ทำให้ฟอร์แมตครอบคลุมตัวเลขเล็กจิ๋วไปจนถึงตัวเลขมหึมาโดยไม่ต้องมี sign สำหรับเลขชี้กำลังแยกอีกช่อง ถ้าเก็บค่า 128 หมายความว่า 2^(128 - 127) = 2^1 นี่คือที่มาของคำว่า "floating" ใน floating-point: จุดฐานสองมันลอยได้
ทำไม 0.1 เก็บแบบเป๊ะ ๆ ไม่ได้. เลข decimal 0.1 เท่ากับ 1/10 แต่ในฐานสอง ค่า 1/10 เป็นเศษส่วนไม่รู้จบ — 0.000110011001100... ไปเรื่อย ๆ IEEE 754 ต้องปัดเศษการขยายอนันต์นี้เหลือ 53 บิตใน binary64 ค่าที่เก็บจึงเป็นเศษส่วน dyadic ที่ใกล้ที่สุดคือ 0.1000000000000000055511151231257827021181583404541015625 ความคลาดเคลื่อนต่อการคำนวณหนึ่งครั้งเล็กนิดเดียวแต่ไม่เคยหายไป นั่นคือเหตุผลที่การบวกซ้ำ ๆ สะสมความเพี้ยน
ค่าพิเศษ. เมื่อช่อง exponent เป็น 1 ล้วน mantissa จะใช้แยกระหว่าง Infinity (ศูนย์ล้วน) กับ NaN (ไม่ใช่ศูนย์) — ลองสลับบิตเข้าไปในสถานะเหล่านี้ดูได้เลย ส่วนเมื่อช่อง exponent เป็นศูนย์ล้วน เลข 1 ที่ซ่อนไว้จะหายไป ค่ากลายเป็น denormal (subnormal) และแลกความละเอียดกับการลดระดับลงสู่ศูนย์อย่างช้า ๆ
ตัวอย่างจริง: 3.14 ใน binary32. sign เป็น 0 เนื่องจาก 3.14 = 1.57 × 2^1 เลขชี้กำลังจริงคือ 1 ช่องที่เก็บจึงเป็น 1 + 127 = 128 หรือ 10000000 ส่วนเศษ 0.57 กลายเป็น mantissa 23 บิตคือ 10010001111010111000011 รวมกันได้ hex 0x4048F5C3 และค่าเท่าตัวที่เก็บคือ 3.1400001049041748046875 — สูงกว่าเลขที่พิมพ์อยู่ราว 0.000000105 ลองใส่ใน explorer ดูแล้วคุณจะเจอบิตเหล่านี้ครบทุกบิต
Practical Use Cases
ดีบักพฤติกรรม floating-point ใน JavaScript
เมื่อยอดรวมพิมพ์ออกมาเป็น 19.990000000000002 หรือเงื่อนไข === ล้มเหลวโดยไม่มีเหตุผล ให้วางตัวถูกดำเนินการทั้งสองตัวลงใน explorer การเทียบบิตแพตเทิร์นสองชุดจะบอกคุณทันทีว่าความไม่ตรงกันนั้นเป็น representation error, ความเพี้ยนที่สะสมมา หรือบั๊กตรรกะจริง ๆ — และโหมด binary64 แสดงตัวเลข JavaScript ตรงตามที่ภาษาเก็บพอดี
ใช้สอน number representation ในห้องเรียน CS
explorer เป็นสไลด์สาธิตสำเร็จรูป: ให้นักเรียนทำนายว่าพลิกบิตหนึ่งบิตแล้วจะเกิดอะไร แล้วค่อยคลิกดูคำตอบ เนื้อหาเรื่อง NaN, Infinity และ denormal ตรงกับโจทย์การบ้านเรื่องมาตรฐาน IEEE 754 ได้เลย และ hex view เชื่อมทฤษฎีในห้องเรียนเข้ากับ memory dump ที่นักเรียนจะเจอในภายหลัง
งาน embedded และโปรโตคอลที่ใช้ float32
เซนเซอร์จำนวนมาก, payload แบบ PLC และไฟล์ไบนารีหลายฟอร์แมตส่งข้อมูลเป็น binary32 ใช้ถอดรหัส hex word ที่รับมาเพื่อตรวจสมมติฐานเรื่อง endianness และ scaling หรือเข้ารหัสค่าที่คาดหวังไว้เทียบทีละช่องตอนเขียนสเปก wire format
ตรวจสอบการ serialize float ข้ามระบบ
เมื่อ float เดินทางข้ามขอบเขต — จากบริการ C++ มาที่ client JavaScript, จาก JSON ลงฐานข้อมูล — การ round-trip มักทิ้งร่องรอยเป็นค่าต่างกันเล็กน้อย การเทียบค่า decimal เท่าตัวสองฝั่งจะแยกให้ได้ว่าเป็นความต่างของ representation ที่ไม่เป็นไร หรือข้อมูลเสียหายจริง
Best Practices
- ใช้ binary64 เพื่อเห็นตัวเลข JavaScript ตามจริง. ค่า Number ใน JS เป็น IEEE 754 double โหมด binary64 จึงเป็นมุมมองที่ซื่อสัตย์ที่สุด ส่วน binary32 เผื่อไว้กับข้อมูล float32 จากระบบอื่น
- เทียบค่า decimal กับค่าเท่าตัวก่อนโทษโค้ดตัวเอง. ยืนยันก่อนว่าความคลาดเคลื่อนเกิดจากฟอร์แมตโดยธรรมชาติ ไม่ใช่บั๊กในการคำนวณของคุณ
- จำไว้ว่า float32 เสียความละเอียดเร็วมาก. มันเก็บได้ราว 7 หลัก decimal อย่าหานำเงินหรือ identifier ไปวิ่งผ่านมัน
- อย่าเทียบความเท่ากันตรง ๆ กับ float ที่คำนวณแล้ว. ให้เทียบกับค่า tolerance แทน และใช้ค่าเท่าตัวช่วยเลือก epsilon ที่สมเหตุสมผล
- เลือกค่าที่แทนได้เป๊ะ ๆ ตอนเขียนเทสต์. ค่าอย่าง 0.5, 0.25 และ 3 ถูกเก็บแบบเป๊ะในฐานสอง เหมาะกับการแยกว่าความเพี้ยนซึมเข้ามาตรงไหน
- ใช้โหมด hex ตอนส่องหน่วยความจำ. คัดลอก hex word ไปแปะใน debugger หรือ memory viewer จะคงบิตครบทุกบิต
เริ่มใช้ IEEE 754 Float Explorer ได้เลย
เลิกเดาว่าทำไม 0.1 ถึงบวกกันแล้วไม่ลงตัว เปิด IEEE 754 Float Explorer ใส่ตัวเลขที่ตามหลอกหลอนคุณลงไป แล้วอ่านคำตอบตรงจากบิต — ฟรี ทันที และเป็น client-side เต็มรูปแบบ
Related Tools You Might Like:
- Base Converter — แปลงตัวเลขระหว่าง binary, octal, decimal และ hex
- ASCII to Binary Converter — ดูว่าข้อความกลายเป็นไบต์และบิตอย่างไร
- Bitwise Calculator — ฝึกใช้ AND, OR, XOR และ shift operation กับค่า binary
ขอให้สนุกกับการเจาะบิต!
คำถามที่พบบ่อย
ถ: ทำไม 0.1 + 0.2 ไม่เท่ากับ 0.3 ใน JavaScript?
ตอบ: ตัวเลขใน JavaScript เป็น IEEE 754 binary64 double ทั้งคู่ ค่า 0.1 และ 0.2 ไม่มีรูปแบบฐานสองที่เป๊ะ ๆ จึงถูกเก็บเป็นเศษส่วนที่ใกล้ที่สุดเท่าที่เป็นไปได้ และผลบวกของทั้งสองไปตกอยู่ห่างจาก double ที่ใกล้ 0.3 ที่สุดออกไปหนึ่ง ULP explorer แสดงค่า decimal เท่าตัวของทั้งสามตัวเลขให้เห็นชัด ๆ
ถ: binary32 กับ binary64 ต่างกันอย่างไร?
ตอบ: binary32 (single precision) ใช้ 1 บิต sign, 8 บิต exponent และ 23 บิต mantissa — ความละเอียดราว 7 หลัก decimal ส่วน binary64 (double precision) ใช้ 1, 11 และ 52 บิต — ราว 15 ถึง 17 หลัก — และเป็นฟอร์แมตที่ JavaScript ใช้กับตัวเลขทุกตัว
ถ: เลข 1 นำหน้าที่ซ่อนไว้คืออะไร?
ตอบ: ค่า IEEE 754 แบบ normalized ทุกค่าขึ้นต้นด้วยเลข 1 หน้าจุดฐานสอง ฟอร์แมตจึงละเว้นการเก็บมันแล้วได้ความละเอียดเพิ่มฟรีหนึ่งบิต explorer จะใส่ 1 ที่ซ่อนไว้นี้กลับเข้าไปตอนสร้างค่าเท่าตัวใหม่
ถ: ข้อมูลของฉันถูกอัปโหลดไปไหนหรือเปล่า?
ตอบ: ไม่ เครื่องมือทำงานทั้งหมดในเบราว์เซอร์แบบ client-side 100% ตัวเลขที่คุณส่องดูจึงไม่เคยออกจากเครื่องของคุณเลย