0

מציג IEEE-754 Float

צפו בדיוק איך מספר עשרוני נשמר כ-Float בתקן IEEE-754 — ביט סימן, ביטי מעריך וביטי מנטיסה — ומדוע מספרים כמו 0.1 אינם נשמרים במדויק.

🔒 מעובד כולו בדפדפן שלך - שום דבר שתזין כאן לא יועלה לעולם.

מעבד... 0%
מנרמל
מחשב הטיית מעריך
מרחיב ביטי מנטיסה
הושלם

תוצאה

כל מספר נקודה צפה שמחשב מאחסן — מספר ב-JavaScript, float ב-C, float ב-Python — מקודד באותה צורה תחת IEEE 754: ביט סימן אחד, גוש של ביטי מעריך, וגוש של ביטי מנטיסה (שבר). דיוק יחיד (32 ביט) משתמש בביט סימן אחד, 8 ביטי מעריך ו-23 ביטי מנטיסה; דיוק כפול (64 ביט), הפורמט שמאחורי סוג המספרים המובנה כמעט בכל שפה, משתמש בביט סימן אחד, 11 ביטי מעריך ו-52 ביטי מנטיסה. כלי זה לוקח כל מספר עשרוני שתקלידו, מקודד אותו בכל אחד מהרוחבים באמצעות מקודד ה-Float המובנה של הדפדפן (DataView/ArrayBuffer) — אותה מכונה שהקוד שלכם רץ עליה בפועל — וצובע כל ביט לפי האזור אליו הוא שייך.

הקידוד עצמו עוקב אחר שלושה שלבים, וכלי זה עובר על כולם במקום להציג רק את הביטים הסופיים. ראשית, נירמול: המספר נכתב מחדש כ-1.mantissa × 2^exponent, עם ספרה אחת בדיוק שאינה אפס לפני הנקודה הבינארית (מספרים קטנים מדי לקבל זאת זוכים לטיפול תת-נורמלי, ללא ה-1 המוביל המובלע). שנית, הטיית מעריך: מאחר ששדה המעריך חייב לאחסן מספרים חיוביים ושליליים כמספר חסר סימן, מוספת הטיה קבועה (127 לדיוק יחיד, 1023 לדיוק כפול) לפני שהשדה נכתב כבינארי. שלישית, המנטיסה השברית מורחבת ביט-אחר-ביט בשיטה הקלאסית של "כפול בשתיים, קח את החלק השלם בתור הביט הבא, והמשך עם השארית" — התהליך חוזר עד ששדה המנטיסה מלא, ואז הביטים הנותרים מכריעים האם התוצאה מעוגלת כלפי מעלה או מטה (עיגול חצי-לזוגי, ברירת המחדל של IEEE-754).

זו בדיוק הסיבה שמספר רגיל כמו 0.1 אינו נשמר בדיוק. בבסיס בינארי, 0.1 הוא שבר מחזורי (0.0001100110011…, לנצח), כך שאף מנטיסה סופית אינה יכולה להחזיק אותו בדיוק — הוא חייב להיות מעוגל בשלב כלשהו. קדדו 0.1 כ-Float של 32 ביט וקיראו את הביטים בחזרה, ולא תקבלו 0.1: תקבלו בדיוק 0.100000001490116119384765625. לדיוק כפול יש 29 ביטי מנטיסה נוספים לעבוד איתם, כך ששגיאת העיגול שלו קטנה בהרבה, אך היא אינה אפס — 0.1 כ-double של 64 ביט הוא בדיוק 0.1000000000000000055511151231257827021181583404541015625. כלי זה מחשב את הערך המאוחסן המדויק בעזרת אריתמטיקה של מספרים שלמים גדולים (ללא קיצורי דרך של נקודה צפה) כך שהפער בין מה שהקלדתם למה שהחומרה באמת שומרת לעולם אינו מוסתר או מקורב.

ערכים מיוחדים מקבלים תבניות ביטים מדויקות ושמורות במקום קידוד רגיל: לאפס ומינוס אפס יש ביטי מעריך ומנטיסה שכולם אפסים (רק ביט הסימן שונה), ±Infinity מקבל ביטי מעריך שכולם אחדים עם מנטיסה שכולה אפסים, ו-NaN מקבל ביטי מעריך שכולם אחדים עם לפחות ביט מנטיסה אחד דלוק. הכל רץ מקומית בדפדפן שלכם — שום דבר מהקלדתכם אינו מועלה לשום מקום — מה שהופך את המקום הזה לבטוח לבניית אינטואיציה אמיתית לבאגים של נקודה צפה: למה `0.1 + 0.2 !== 0.3` כמעט בכל שפת תכנות, למה טקסטורות float32 בקוד גרפי מאבדות דיוק ש-float64 לא יאבד, ולמה קוד פיננסי צריך בדרך-כלל להימנע לחלוטין מנקודה צפה בינארית.