IEEE-754 โฟลตวิชวลไลเซอร์
ดูว่าตัวเลขทศนิยมถูกจัดเก็บในรูปแบบทศนิยม IEEE-754 อย่างไร เช่น บิตเครื่องหมาย บิตเอ็กซ์โปเนนต์ และบิตแมนทิสซา และเหตุใดตัวเลข เช่น 0.1 จึงไม่ได้รับการจัดเก็บอย่างถูกต้องแม่นยำ
ผลลัพธ์
หมายเลขทศนิยมทุกตัวที่คอมพิวเตอร์จัดเก็บ เช่น หมายเลข JavaScript, C float, Python float จะได้รับการเข้ารหัสในลักษณะเดียวกันภายใต้ IEEE 754: บิตเครื่องหมายหนึ่งบิต บล็อกของบิตเลขชี้กำลัง และบล็อกของบิตแมนทิสซา (เศษส่วน) ความแม่นยำเดี่ยว (32 บิต) ใช้ 1 บิตสัญญาณ, 8 บิตเอ็กซ์โปเนนต์ และ 23 บิตแมนทิสซา double precision (64-bit), the format behind almost every language's default number type, uses 1 sign bit, 11 exponent bits and 52 mantissa bits. เครื่องมือนี้ใช้เลขทศนิยมที่คุณพิมพ์ เข้ารหัสด้วยความกว้างใดก็ได้โดยใช้ตัวเข้ารหัส DataView/ArrayBuffer float ของเบราว์เซอร์ ซึ่งเป็นกลไกเดียวกับที่โค้ดของคุณใช้งานจริง และให้สีแต่ละบิตตามภูมิภาคที่เป็นอยู่
การเข้ารหัสนั้นทำตามสามขั้นตอน และเครื่องมือนี้จะอธิบายขั้นตอนทั้งหมดแทนที่จะแสดงเพียงบิตสุดท้าย First, normalization: the number is rewritten as 1.mantissa × 2^exponent, with exactly one nonzero digit before the binary point (numbers too small for that get the subnormal treatment instead, with no implicit leading 1). ประการที่สอง อคติของเลขชี้กำลัง: เนื่องจากช่องเลขชี้กำลังต้องเก็บเลขชี้กำลังทั้งบวกและลบเป็นตัวเลขที่ไม่ได้ลงนาม ค่าอคติคงที่ (127 สำหรับความแม่นยำเดี่ยว 1,023 สำหรับความแม่นยำสองเท่า) จะถูกเพิ่มก่อนที่ฟิลด์จะถูกเขียนในรูปแบบไบนารี ประการที่สาม แมนทิสซาเศษส่วนจะถูกขยายทีละนิดด้วยวิธีคลาสสิก “คูณด้วยสอง เอาส่วนจำนวนเต็มเป็นบิตถัดไป เก็บส่วนที่เหลือ” — ทำซ้ำจนกว่าฟิลด์แมนทิสซาจะเต็ม จากนั้นบิตที่เหลือจะตัดสินว่าผลลัพธ์จะปัดขึ้นหรือลง (ปัดเศษครึ่งถึงคู่ ค่าเริ่มต้นของ IEEE-754)
นี่คือเหตุผลว่าทำไมตัวเลขธรรมดาอย่าง 0.1 จึงไม่ได้จัดเก็บไว้เป๊ะๆ In binary, 0.1 is a repeating fraction (0.0001100110011…, forever), so no finite mantissa can hold it precisely — it has to be rounded off somewhere. เข้ารหัส 0.1 เป็นทศนิยม 32 บิตแล้วอ่านบิตกลับ และคุณจะไม่ได้รับ 0.1 กลับ: คุณจะได้รับ 0.100000001490116119384765625 พอดี ความแม่นยำสองเท่ามีบิตแมนทิสซาอีก 29 บิตที่ใช้งานได้ ดังนั้นข้อผิดพลาดในการปัดเศษจึงน้อยกว่ามาก แต่ก็ไม่เป็นศูนย์เช่นกัน - 0.1 เนื่องจากสองเท่าแบบ 64 บิตคือ 0.1000000000000000055511151231257827021181583404541015625 พอดี เครื่องมือนี้จะคำนวณค่าที่เก็บไว้ที่แน่นอนด้วยเลขคณิตจำนวนเต็มขนาดใหญ่ (ไม่มีทางลัดจุดทศนิยม) ดังนั้นช่องว่างระหว่างสิ่งที่คุณพิมพ์และสิ่งที่ฮาร์ดแวร์เก็บไว้จริงจะไม่ถูกซ่อนหรือประมาณ
ค่าพิเศษจะได้รูปแบบบิตที่สงวนไว้ที่แน่นอนมากกว่าการเข้ารหัสปกติ: ศูนย์และศูนย์ลบจะมีเลขชี้กำลังเป็นศูนย์ทั้งหมดและบิตแมนทิสซา (เฉพาะบิตเครื่องหมายเท่านั้นที่แตกต่างกัน) ±อินฟินิตี้มีบิตเลขชี้กำลังทั้งหมดหนึ่งบิตพร้อมกับแมนทิสซาที่เป็นศูนย์ทั้งหมด และ NaN มีบิตเลขชี้กำลังทั้งหมดหนึ่งบิตที่มีชุดบิตแมนทิสซาอย่างน้อยหนึ่งชุด Everything here runs locally in your browser — nothing you type is uploaded anywhere — which makes this a safe place to build real intuition for floating-point bugs: why `0.1 + 0.2 !== 0.3` in almost every programming language, why float32 textures in graphics code lose precision that float64 wouldn't, and why financial code should generally avoid binary floating point altogether.