חשבון נקודה צפה

ברוכים הבאים לפרק נוסף של Under The Hood . טור זה נועד לתת למפתחי ג'אווה הצצה ליופי הנסתר מתחת לתוכניות הג'אווה הרצות שלהם. הטור החודש ממשיך את הדיון, שהחל בחודש שעבר, על מערך ההוראות של bytecode של מכונת הווירטואלית Java (JVM). מאמר זה בוחן חשבון חשבוני עם נקודה צפה ב- JVM, ומכסה את קודי ה- bytec שמבצעים פעולות חשבון נקודתיות צפות. המאמרים הבאים ידונו בבני משפחה אחרים.

הנקודות הצפות העיקריות

תמיכת הנקודות הצפות של JVM עומדת בתקן הנקודות הצפות של IEEE-754 1985. תקן זה מגדיר את הפורמט של מספרים של 32 סיביות ו -64 סיביות ומגדיר את הפעולות על המספרים הללו. ב- JVM, חשבון בנקודות צפות מתבצע על צף של 32 סיביות וכפולות של 64 סיביות. לכל קוד-byt שמבצע חשבון על צף, ישנו קוד-byt מקביל המבצע את אותה פעולה בכפולות.

למספר נקודה צפה יש ארבעה חלקים - סימן, מנטיסה, רדיקל ומעריך. השלט הוא 1 או -1. המנטיסה, תמיד מספר חיובי, מחזיקה את הספרות המשמעותיות של המספר הנקודה הצפה. האקספוננט מציין את הכוח החיובי או השלילי של הרדיקס שיש להכפיל את המנטיסה והסימן. ארבעת המרכיבים משולבים כדלקמן כדי לקבל את ערך הנקודה הצפה:

סימן * מנטיסה * אקספוננט

למספרים של נקודה צפה יש ייצוגים מרובים, מכיוון שאפשר תמיד להכפיל את המנטיסה של כל מספר נקודה צפה בכוח כלשהו של הרדיקס ולשנות את האקספוננט כדי לקבל את המספר המקורי. לדוגמה, המספר -5 יכול להיות מיוצג באותה מידה על ידי אחת מהצורות הבאות ברדיקס 10:

טפסים של -5
סִימָן מַנטִיסָה מערך רדיקס
-1 50 10 -1
-1 5 10 0
-1 0.5 10 1
-1 0.05 10 2

לכל מספר נקודה צפה יש ייצוג אחד שאומרים שהוא מנורמל. מספר נקודה צפה מנורמל אם המנטיסה שלו נמצאת בטווח המוגדר על ידי היחס הבא:

1 / רדיקס <= מנטיסה <

למספר הנקודות הצפות של רדיקל 10 מנורמל יש את הנקודה העשרונית ממש משמאל לספרה הראשונה שאינה אפסית במנטיסה. הייצוג של נקודה צפה מנורמלת של -5 הוא -1 * 0.5 * 10 1. במילים אחרות, למנטיסה של מספר נקודה צפה מנורמל אין ספרות שאינן אפסות משמאל לנקודה העשרונית וספרה שאינה אפס רק כדי ימין של הנקודה העשרונית. אומרים שכל מספר של נקודה צפה שאינו מתאים לקטגוריה זו הוא מנוורמלי . שים לב שלמספר אפס אין ייצוג מנורמל, מכיוון שאין לו ספרה שאינה אפס לשים רק מימין לנקודה העשרונית. "למה להיות מנורמל?" הוא קריאה נפוצה בקרב אפסים.

מספרי נקודות צפות ב- JVM משתמשים ברדיקס של שניים. לכן מספרים של נקודות צף ב- JVM הם בעלי הצורה הבאה:

סימן * מנטיסה * 2 מעריך

המנטיסה של מספר נקודה צפה ב- JVM מתבטאת כמספר בינארי. למנטיסה מנורמלת יש את הנקודה הבינארית שלה (המקבילה לשניים בסיס של נקודה עשרונית) ממש משמאל לספרה המשמעותית ביותר שאינה אפסית. מכיוון שלמערכת המספרים הבינאריים יש רק שתי ספרות - אפס ואחת - הספרה המשמעותית ביותר של מנטיסה מנורמלת היא תמיד ספרה.

החלק המשמעותי ביותר של צף או כפול הוא סיבית הסימן שלו. המנטיסה תופסת את 23 החלקים הכי פחות משמעותיים של צף ואת 52 החלקים הכי פחות משמעותיים של כפול. האקספוננט, 8 סיביות בצוף ו -11 סיביות בכפול, יושב בין השלט למנטיסה. הפורמט של מצוף מוצג להלן. סיבית הסימן מוצגת כ- "s", סיביות האקספוננט מוצגות כ- "e", וסיביות המנטיסה מוצגות כ- "m":

פריסת סיביות של Java צף
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm

ביט סימן של אפס מציין מספר חיובי וסימן ביט של אחד מציין מספר שלילי. המנטיסה מתפרשת תמיד כמספר חיובי-שניים. זה לא מספר דו-משלים. אם ביט הסימן הוא אחד, ערך הנקודה הצפה הוא שלילי, אך המנטיסה עדיין מתפרשת כמספר חיובי שיש להכפיל ב -1.

שדה האקספוננט מתפרש באחת משלוש דרכים. מעריך של כל אלה מציין שלמספר הנקודה הצפה יש אחד מהערכים המיוחדים של אינסוף פלוס מינוס, או "לא מספר" (NaN). NaN הוא תוצאה של פעולות מסוימות, כגון חלוקת אפס באפס. מעריך של כל האפסים מציין מספר נקודה צפה מונורמלי. כל מעריך אחר מציין מספר נקודה צפה מנורמל.

המנטיסה מכילה סיבית נוספת נוספת של דיוק מעבר לאלה המופיעים בסיביות המנטיסה. למנטיסה של מצוף, שתופסת 23 סיביות בלבד, יש 24 סיביות דיוק. למנטיסה של כפול, שתופס 52 ביט, יש 53 ביטים של דיוק. סיבית המנטיסה המשמעותית ביותר ניתנת לחיזוי ולכן אינה נכללת מכיוון שמעריך המספרים עם נקודה צפה ב- JVM מציין אם המספר מנורמל או לא. אם המעריך הוא כולו אפסים, המספר של הנקודה הצפה הוא מנורמל והידוע שהסיבית המשמעותית ביותר במנטיסה היא אפס. אחרת, מספר הנקודה הצפה מנורמל והידוע שהסיבוב המשמעותי ביותר של המנטיסה הוא אחד.

ה- JVM אינו מוציא חריגים כתוצאה מפעולות נקודה צפה כלשהי. ערכים מיוחדים, כמו אינסוף חיובי ושלילי או NaN, מוחזרים כתוצאה מפעולות חשודות כמו חלוקה באפס. מעריך של כל אלה מציין ערך נקודה צפה מיוחדת. מעריך של כל אלה עם מנטיסה שכל החלקים שלהם אפס מעיד על אינסוף. סימן האינסוף מסומן על ידי ביט הסימן. מעריך של כל אלה עם כל מנטיסה אחרת מתפרש כמשמעותו "לא מספר" (NaN). ה- JVM מייצר תמיד את אותה מנטיסה עבור NaN, שכולה אפסים למעט סיבית המנטיסה המשמעותית ביותר המופיעה במספר. ערכים אלה מוצגים לצוף מתחת:

ערכי צף מיוחדים
ערך ביטים צפים (סימן מעריך מנטיסה)
אינסוף 0 11111111 00000000000000000000000
-אינסוף 1 11111111 00000000000000000000000
NaN 1 11111111 10000000000000000000000

מעריצים שאינם כולם אלה ולא כל האפסים מצביעים על כוחם של שניים באמצעותם להכפיל את המנטיסה המנורמלת. ניתן לקבוע את העוצמה של שניים על ידי פירוש הביטים המעריכים כמספר חיובי, ואז הפחתת הטיה מהמספר החיובי. עבור מצוף, ההטיה היא 126. עבור כפול, ההטיה היא 1023. לדוגמא, שדה מעריכי בצוף של 00000001 מניב כוח של שניים על ידי חיסור ההטיה (126) משדה המעריך המתפרש כמספר שלם חיובי (1). כוחם של שניים, אם כן, הוא 1 - 126, שהוא -125. זהו הכוח הקטן ביותר האפשרי מבין שניים לצוף. בקצה השני, שדה מעריכי של 11111110 מניב עוצמה של שניים של (254 - 126) או 128. המספר 128 הוא העוצמה הגדולה ביותר מבין שניים העומדים לרחפה. מספר דוגמאות לצפים מנורמלים מוצגות בטבלה הבאה:

ערכי צף מנורמל
ערך ביטים צפים (סימן מעריך מנטיסה) מעריך לא מוטה
הציפה החיובית (הסופית) הגדולה ביותר 0 11111110 11111111111111111111111 128
הציפה השלילית (הסופית) הגדולה ביותר 1 11111110 11111111111111111111111 128
הציפה הנורמלית הקטנה ביותר 1 00000001 00000000000000000000000 -125
פאי 0 10000000 10010010000111111011011 2

מעריך של כל האפסים מציין כי המנטיסה אינה מנוורלת, כלומר הסיבית המובילה הלא-מוגדרת היא אפס במקום אחד. כוחם של שניים במקרה זה זהה לעוצמה הנמוכה ביותר מבין שניים שניתן למנטיסה מנורמלת. עבור המצוף, זה -125. המשמעות היא שלמנטיסות מנורמלות המוכפלות בשניים שהועלו לכוח של -125 יש שדה מעריכי של 00000001, בעוד שלמנמות מנורמלות כפול שניים שהועלו לכוח של -125 יש שדה אקספוננט של 00000000. סוף טווח המעריכים תומך בהזרמה הדרגתית. אם במקום זאת נעשה שימוש במעריך הנמוך ביותר לייצוג מספר מנורמל, תתגלה זרימה לאפס עבור מספרים גדולים יותר. במילים אחרות, השארת האקספוננט הנמוך ביותר למספרים לא מורמלים מאפשרת לייצג מספרים קטנים יותר.למספרים הקטנים המנורמליים יש פחות פיסות דיוק ממספרים מנורמלים, אך עדיף על פני זרימה נמוכה לאפס ברגע שהמעריך מגיע לערכו המינימלי הנורמלי.

ערכים צפים מנורמל
ערך ביטים צפים (סימן מעריך מנטיסה)
הצף החיובי הקטן ביותר (לא אפס) 0 00000000 00000000000000000000001
הציפה השלילית הקטנה ביותר (ללא אפס) 1 00000000 00000000000000000000001
הגדול ביותר לצוף מנורמל 1 00000000 11111111111111111111111
אפס חיובי 0 00000000 00000000000000000000000
אפס שלילי 1 00000000 00000000000000000000000

צף חשוף

צף ג'אווה חושף את אופיו הפנימי היישומון שלמטה מאפשר לך לשחק בפורמט הנקודה הצפה. הערך של מצוף מוצג בכמה פורמטים. פורמט הסימון המדעי של רדיקס שני מראה את המנטיסה והמערך בבסיס עשר. לפני הצגתו, המנטיסה בפועל מוכפלת ב -2 24, שמניב מספר אינטגרלי, והמערך הבלתי משוחד מצטמצם ב- 24. גם המנטיסה האינטגרלית וגם המעריך הופכים בקלות לבסיס עשר ומוצגים.