Transcript C4_floating

Floating Point
‫מבוסס על‬
Computer systems – a programmer’s perspective / Bryant & Ohallaron
‫נושאים‬
IEEE ‫הסטנדרט של‬
)Rounding( ‫עיגול‬
‫פעולות‬
‫תכונות מתמטיות‬




‫חידות‬
int a = 4 / 3;
:‫פלט‬
a = 1
printf(“a = %d”, a);
float a = 4 / 3;
a = 1.000000
printf(“a = %f”, a);
float a = 4.0 / 3.0;
a = 1.333333
printf(“a = %f”, a);
float a = 4.0 / 3.0;
printf(“a = %4.20f”, a);
–2–
a = 1.33333337306976318359
‫חידות‬
float a = 0.25;
printf(“a = %4.20f”, a);
:‫פלט‬
a = 0.25000000000000000000
float a = 0.20;
printf(“a = %4.20f”, a);
a = 0.20000000298023223877
double a = 0.20;
printf(“a = %4.20f”, a);
–3–
a = 0.20000000000000001110
‫הסטנדרט ‪IEEE Floating Point‬‬
‫סטנדרט ‪IEEE Standard 754‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫החל מ ‪1985‬‬
‫נתמך על ידי רב המעבדים‬
‫המטרה‪ :‬סטנדרטיזציה של נושאים כמו עיגול וגלישה‪.‬‬
‫–‪–4‬‬
‫שברים בינאריים‬
‫‪2i‬‬
‫‪2i–1‬‬
‫‪4‬‬
‫‪2‬‬
‫‪1‬‬
‫‪b–j‬‬
‫•••‬
‫•••‬
‫‪b2 b1 b0 . b–1 b–2 b–3‬‬
‫•••‬
‫‪bi bi–1‬‬
‫‪1/2‬‬
‫‪1/4‬‬
‫‪1/8‬‬
‫•••‬
‫‪2–j‬‬
‫ייצוג‬
‫‪‬‬
‫‪‬‬
‫סיביות מימין לנקודה מייצגות שברים בחזקות של ‪2‬‬
‫‪i‬‬
‫מייצג מספרים רציונליים‪:‬‬
‫‪k‬‬
‫‪ bk 2‬‬
‫‪k  j‬‬
‫–‪–5‬‬
‫דוגמאות של שברים בינאריים‬
‫‪Representation‬‬
‫‪101.112‬‬
‫‪10.1112‬‬
‫‪0.1111112‬‬
‫‪Value‬‬
‫‪5 3/4‬‬
‫‪2 7/8‬‬
‫‪63/64‬‬
‫נשים לב‬
‫‪‬‬
‫חלוקה והכפלה ב ‪ 2‬על ידי ‪shifting‬‬
‫‪‬‬
‫מספרים מהצורה ‪ 0.111111…2‬קרובים ל – ‪1.0‬‬
‫‪1/2 + 1/4 + 1/8 + … + 1/2i + …  1.0 ‬‬
‫‪ ‬נוהגים לכתוב ‪1.0 – ‬‬
‫–‪–6‬‬
‫אילו מספרים ניתן לייצג ?‬
‫מגבלה‬
‫‪‬‬
‫יכול לייצג רק מספרים מהצורה ‪x/2k‬‬
‫‪‬‬
‫מספרים אחרים מיוצגים על ידי תבנית חוזרת‪:‬‬
‫‪Value‬‬
‫‪float‬‬
‫‪Representation‬‬
‫…‪0.33333334326744‬‬
‫‪0.0101010101[01]…2‬‬
‫‪1/3‬‬
‫…‪0.20000000298023‬‬
‫‪0.00110011[0011]…2‬‬
‫‪1/5‬‬
‫‪0.000110011[0011]…2‬‬
‫‪0.10000000149011..‬‬
‫‪1/10‬‬
‫–‪–7‬‬
‫ייצוג‬
‫‪‬‬
‫‪‬‬
‫‪ s‬קובע אם המספר הוא שלילי או חיובי‬
‫‪ - M‬מספר בטווח )‪[1.0,2.0‬‬
‫‪ ‬נראה בקרוב שהוא יכול להיות גם בטווח )‪[0.0, 1.0‬‬
‫‪‬‬
‫‪‬‬
‫‪' E‬המשקל' של המספר בחזקות של ‪.2‬‬
‫הערך (בבסיס ‪ )2‬הוא‪–1s M 2E:‬‬
‫‪exp‬‬
‫‪frac‬‬
‫‪M‬‬
‫‪E‬‬
‫‪s‬‬
‫‪Sign‬‬
‫‪bit‬‬
‫–‪–8‬‬
...‫ניתן לשלוט על הדיוק‬
s
exp
frac
‫גדלים‬

Single precision: 8 exp bits, 23 frac bits
 32 bits total

Double precision: 11 exp bits, 52 frac bits
 64 bits total

Extended precision: 15 exp bits, 63 frac bits
 Stored in 80 bits
» 1 bit wasted
–9–
‫הטיה ‪biasing -‬‬
‫‪ exp ‬צריך לייצג גם חזקות חיוביות וגם חזקות שליליות‪ .‬למשל‪:‬‬
‫‪2-34‬‬
‫‪271‬‬
‫‪ ‬ניתן היה לייצג את המספר עם ‪ 2’s complement‬אבל מסיבות‬
‫שונות זה מקשה על חישובים‪.‬‬
‫‪ ‬לכן מבצעים המרה של הערך למספר ‪ unsigned‬על ידי 'הטיה'‬
‫בגודל ‪. 2exp-1-1‬‬
‫‪‬‬
‫למשל‪ ,‬כשהרוחב של ‪ exp‬הוא ‪ ,8‬אז ההטיה היא ב ‪.127‬‬
‫‪‬‬
‫חוצה את הטווח לחיוביים ושליליים‪.‬‬
‫– ‪– 10‬‬
‫דוגמה‬
‫) מקור – ‪)wikipedia‬‬
‫‪−118.625‬‬
‫‪11810 = 11101102‬‬
‫‪0.62510 = 1*2-1 + 0*2-2 + 1 * 2-3 = .1012‬‬
‫‪ ‬כלומר המספר שלנו הוא ‪ 1110110.101‬או ‪1.110110101x26‬‬
‫‪ ‬השבר )‪ (frac‬יכיל אם כן את ‪ 110110101‬וימולא באפסים מימין‪.‬‬
‫‪ ‬מה עם האקספוננט )‪ ?6 (exp‬לכאורה צריך להיות ‪exp = 610 = 1102‬‬
‫‪‬‬
‫‪...‬אבל מבצעים הטיה בגודל ‪ 127‬ולכן מקודדים את‬
‫‪6 + 127 = 13310 = 100001012‬‬
‫– ‪– 11‬‬
‫קטגוריות של מספרים‬
‫‪ ‬מקרים מיוחדים‪:‬‬
‫שימו לב שזה אחרי‬
‫הטיה‪ ,‬כלומר מוותרים‬
‫על האפשרות לחזקה‬
‫של ‪-127‬‬
‫‪‬‬
‫אם …‪ exp=000‬ו …‪ frac = 000‬אז המספר הוא ‪ 0‬או ‪ ,-0‬בהתאם לסימן‪.‬‬
‫‪‬‬
‫אם …‪ exp = 000‬ו ‪ frac > 0‬אזי המספר הוא ‪0.frac‬‬
‫‪ ‬מספרים אלה נקראים ‪.denormalized numbers‬‬
‫‪ ‬המספרים ה 'רגילים' שראינו )‪ (1.frac‬נקראים ‪.normalized‬‬
‫‪‬‬
‫אם …‪ exp = 111‬ו …‪ frac = 000‬מייצג ‪ ± ‬בהתאם לסימן‬
‫‪‬‬
‫אם …‪ exp = 111‬ו ‪ frac > 0‬מיצג )‪‘Not A Number’ (NaN‬‬
‫‪ ‬כך למשל תיוצג התוצאה של )‪.sqrt(-1‬‬
‫– ‪– 12‬‬
‫מספרים קטנים‪(denormalized) ...‬‬
‫‪ ‬התקן של ‪ IEEE‬קובע שההטיה עבור ‪ denormalized‬היא‬
‫‪ 1 – bias‬ולא ‪.-bias‬‬
‫‪‬‬
‫מדוע ? יוצר רציפות עם ‪ .normalized‬דוגמה בספר (עמ' ‪.)86‬‬
‫‪ ‬דוגמה‪ :‬נניח ש ‪ .|exp| = 4‬אז ‪ bias = 7‬אבל ההטיה ב‬
‫‪ denormalized‬תהיה ‪.1 – 7 = -6‬‬
‫‪ ‬מכיוון ש ‪ exp = 000‬אז כל המספרים ב ‪denormalized‬‬
‫מוכפלים ב ‪ .2-6‬נותן לנו צפיפות גבוהה קרוב ל – ‪.0‬‬
‫– ‪– 13‬‬
‫ מפת המספרים העשרוניים‬:‫סיכום‬

NaN
– 14 –
-Normalized
+Denorm
-Denorm
0
+0
+Normalized
+
NaN
‫התפלגות של ערכים מותרים‬
6-bit IEEE-like format



e = 3 exponent bits
f = 2 fraction bits
Bias is 3
.0 – ‫הצפיפות גדלה כשמתקרבים ל‬
-15
– 15 –
-10
-5
Denormalized
0
5
Normalized Infinity
10

15
)‫התפלגות של ערכים מותרים (מבט מקרוב‬
6-bit IEEE-like format



-1
– 16 –
e = 3 exponent bits
f = 2 fraction bits
Bias is 3
-0.5
Denormalized
0
Normalized
0.5
Infinity
1
‫עיגול ב ‪floating-point‬‬
‫‪ ‬ניתן לחשוב על זה כך‪...‬‬
‫‪‬‬
‫‪‬‬
‫דבר ראשון חשב את התוצאה המדויקת‬
‫אח"כ התאם את זה למה שניתן לפי רמת הדיוק שנקבעה‪.‬‬
‫‪ ‬תיתכן גלישה אם החלק השלם גדול מדי‬
‫‪ ‬ייתכן צורך בעיגול בחלק העשרוני‬
‫‪ ‬התקן תומך במספר אפשרויות 'עיגול' )‪(Rounding Modes‬‬
‫‪‬‬
‫‪–1.50‬‬
‫‪2.50‬‬
‫‪1.50‬‬
‫‪1.60‬‬
‫‪1.40‬‬
‫‪–1‬‬
‫‪2‬‬
‫‪1‬‬
‫‪1‬‬
‫‪1‬‬
‫‪Zero‬‬
‫‪‬‬
‫‪–2‬‬
‫‪–1‬‬
‫‪–2‬‬
‫‪2‬‬
‫‪3‬‬
‫‪2‬‬
‫‪1‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪2‬‬
‫‪2‬‬
‫‪1‬‬
‫‪2‬‬
‫‪1‬‬
‫)‪Round down (-‬‬
‫)‪Round up (+‬‬
‫)‪Nearest Even (default‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫זאת רק הדגמה של אפשרויות העיגול‪ .‬בפועל העיגול נעשה ברמת הסיביות‬
‫כשהמטרה היא לעגל למספר עשרוני קרוב‪ ,‬לא למספר שלם‪.‬‬
‫– ‪– 17‬‬
‫נסתכל שוב על ‪Nearest-Even‬‬
‫זאת ברירת המחדל‬
‫‪‬‬
‫‪‬‬
‫ניתן לשנות זאת רק על ידי מתן פקודות ברמה של שפת המכונה‪.‬‬
‫כל אפשרויות העיגול האחרות סובלות מהטיה סטטיסטית‪.‬‬
‫‪ ‬למשל‪ ,‬סכום מספרים חיוביים תמיד יהיה מקורב מלמעלה ב ‪round-up‬‬
‫נראה איך שיטה זאת מיושמת במקומות אחרים אחרי הנקודה ‪/‬‬
‫ברמת הסיביות‪.‬‬
‫‪‬‬
‫כל פעם שנמצאים בדיוק באמצע בין שני ערכים אפשריים‬
‫‪ ‬נעגל כך שהסיבית הימנית היא 'זוגית' (‪.)0‬‬
‫‪‬‬
‫דוגמה‪ :‬עיגול למאית הקרובה‪.‬‬
‫‪ 1.24‬מסתיים‬
‫בספרה זוגית‪ .‬לכן‬
‫יש לו עדיפות על‬
‫האלטרנטיבות‪:‬‬
‫‪ 1.25‬ו ‪1.23‬‬
‫)‪(Less than half way‬‬
‫)‪(Greater than half way‬‬
‫)‪(Half way—round up‬‬
‫)‪(Half way—round down‬‬
‫‪1.23‬‬
‫‪1.24‬‬
‫‪1.24‬‬
‫‪1.24‬‬
‫‪1.2349999‬‬
‫‪1.2350001‬‬
‫‪1.2350000‬‬
‫‪1.2450000‬‬
‫– ‪– 18‬‬
‫עיגול מספרים בינאריים‬
‫שברים בינאריים‪...‬‬
‫‪‬‬
‫‪‬‬
‫'זוגי' = ספרה ימנית היא ‪0‬‬
‫אמצע הדרך = …‪ 1000‬מימין לנקודה בה יש לעגל‪.‬‬
‫דוגמאות‪:‬‬
‫‪‬‬
‫פחות מנקודת‬
‫החצי …‪100‬‬
‫עיגול ל – ¼ (‪ 2‬סיביות מימין לנקודה)‬
‫‪Rounded Value‬‬
‫‪2‬‬
‫‪2 1/4‬‬
‫‪3‬‬
‫‪2 1/2‬‬
‫‪Action‬‬
‫)‪(<1/2—down‬‬
‫)‪(>1/2—up‬‬
‫)‪(1/2—up‬‬
‫)‪(1/2—down‬‬
‫‪Rounded‬‬
‫‪10.002‬‬
‫‪10.012‬‬
‫‪11.002‬‬
‫‪10.102‬‬
‫השאלה היא אם להוסיף ‪ 1‬או‬
‫לא‪ ...‬אם נוסיף ‪ 1‬זה יהפוך 'זוגי'‬
‫ל'אי זוגי' לכן לא נוסיף‪.‬‬
‫‪Binary‬‬
‫‪10.000112‬‬
‫‪10.001102‬‬
‫‪10.111002‬‬
‫‪10.101002‬‬
‫‪Value‬‬
‫‪2 3/32‬‬
‫‪2 3/16‬‬
‫‪2 7/8‬‬
‫‪2 5/8‬‬
‫– ‪– 19‬‬
‫פעולות ב ‪floating point‬‬
‫‪ ‬לא נכנס לפרטים של איך מבוצע חיבור‪ ,‬כפל‪... ,‬‬
‫‪ ‬חשוב לדעת ש‪:‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫אין שבירה של גבולות ה ‪ exp, frac, sign‬גם במקרה של גלישה‪.‬‬
‫כתוצאה מכך אין גלישה ממספר חיובי לשלילי ולהפך‪.‬‬
‫בניגוד ל ‪ ,Int‬לא מתבצע חישוב ‪ .modular arithmetic‬במקום זה‪:‬‬
‫‪ ‬גלישה מלמעלה = ‪+‬‬
‫‪ ‬גלישה מלמטה = ‪-‬‬
‫‪‬‬
‫‪‬‬
‫פעולות על ‪ ‬מוגדרות (למשל‪ ,)5 +    ,‬לכן ניתן לבדוק גלישה בסוף‬
‫שרשרת חישובים במקום אחרי כל צעד‪.‬‬
‫יש גם ‪ :underflow‬כשהמספר המיוצג קרוב מאוד ל ‪ 0‬אך לא ניתן לייצוג‪,‬‬
‫הוא יהפוך ל ‪.0‬‬
‫– ‪– 20‬‬
‫צרות‪ ,‬צרות‪...‬‬
‫האם‬
‫)‪(3.14 + 1e10) – 1e10 = 3.14 + (1e10 – 1e10‬‬
‫תשובה‪ :‬לא‪ .‬בשל עיגול ‪.3.14 + 1e10 = 1e10‬‬
‫‪(1001010100000010111110010000000000)2‬‬
‫= ‪(1e10)10‬‬
‫‪(3.14 + 1e10)10 = (1001010100000010111110010000000011)2‬‬
‫ספרה ‪33‬‬
‫מהווה בעיה בחישובים מדויקים‪ ,‬וכן במהדרים‪.‬‬
‫– ‪– 21‬‬
‫‪ float‬מגביל אופטימיזציות אפשריות במהדרים‬
‫בהינתן קוד‬
‫;‪x = a + b + c‬‬
‫;‪y = b + c + d‬‬
‫המהדר יכול לעשות אופטימיזציה כדלהלן‪:‬‬
‫;‪t = b + c‬‬
‫;‪x = a + t‬‬
‫;‪y = t + d‬‬
‫אבל ב ‪ float‬זה לא בהכרח נכון כפי שראינו‪ .‬אסוציאטיביות לא‬
‫נשמרת‪.‬‬
‫לכן אופטימיזציה זאת לא תתבצע‪.‬‬
‫– ‪– 22‬‬
‫‪ Floating Point‬ב ‪C‬‬
‫‪ C‬מאפשר שתי רמות דיוק‪:‬‬
‫‪float‬‬
‫‪double‬‬
‫‪single precision‬‬
‫‪double precision‬‬
‫המרות טיפוס‬
‫‪ ‬המרות בין ‪ int, float, double‬משנה את הערכים !‬
‫‪ ‬מ ‪ Double‬או ‪ float‬ל ‪int‬‬
‫‪ ‬מוריד את החלק העשרוני‬
‫‪ ‬כמו עיגול לכיוון ה – ‪.0‬‬
‫‪ ‬לא מוגדר כשמחוץ לתחום‬
‫– ‪– 23‬‬
‫‪ Floating Point‬ב ‪C‬‬
‫המרות (המשך)‬
‫‪‬‬
‫מ ‪ int‬ל ‪double‬‬
‫‪ ‬המרה מדויקת‪ ,‬כל עוד ‪ int‬מוגדר מעל רוחב מילה ‪≤ 53‬‬
‫‪‬‬
‫מ ‪ int‬ל ‪float‬‬
‫‪ ‬הייצוג משתנה‪.‬‬
‫‪ ‬אם גודל ה ‪ int‬גדול מהגודל המוקדש ל ‪ frac‬יש צורך בעיגול‪ .‬עיגול לפי ה‬
‫‪.rounding mode‬‬
‫– ‪– 24‬‬
C ‫חידות ב‬
int x = …;
float f = …;
Assume neither
d nor f is NAN
double d = …;
• x == (int)(float) x
No: 24 bit significand
• x == (int)(double) x
Yes: 53 bit significand
• f == (float)(double) f
Yes: increases precision
• d == (float) d
No: loses precision
• f == -(-f);
Yes: Just change sign bit
• 2/3 == 2/3.0
No: 2/3 == 0
• d < 0.0  ((d*2) < 0.0)
Yes!
• d > f
 -f > -d
Yes!
• d * d >= 0.0
Yes!
• (d+f)-d == f
No: Not associative
– 25 –
‫המקרה של ‪Ariane 5‬‬
‫‪‬‬
‫‪‬‬
‫החללית התפוצצה פחות מדקה‬
‫לאחר השיגור‪.‬‬
‫מטען בשווי ‪ 0.5‬מיליארד דולר‪.‬‬
‫למה ?‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫חישב מהירות אופקית‬
‫כמספר ‪ float‬ברוחב ‪64‬‬
‫סיביות‪.‬‬
‫ביצע המרת טיפוס ל ‪int‬‬
‫ברוחב ‪.16‬‬
‫בערכי המהירות והזויות של‬
‫‪ Ariane 4‬לא היתה בעיה‪.‬‬
‫ב ‪ Ariane 5‬הוקלט ערך שגרם‬
‫לגלישה‪ .‬הגלישה גרמה‬
‫לפסיקה (‪)processor-trap‬‬
‫שלא טופלה ועצרה את‬
‫– ‪– 26‬‬
‫המעבד‪.‬‬
‫דוגמאות נוספות‬
‫‪ ‬באג בטיל ה'פטריוט'‪ ,‬אשר גרם למותם של ‪ 28‬חילים אמריקאים‬
‫ב ‪( Daharan‬ערב הסעודית) ב ‪25.2.91‬‬
‫‪‬‬
‫‪‬‬
‫הרדאר מזהה טיל על פי מודל צפוי של התקדמותו ("בעוד ‪ x‬מילי שניות‬
‫הטיל צריך להיות במיקום ‪.)"y‬‬
‫השעון יוצג על ידי משתנה ‪ float‬ובמשך הזמן צבר אי דיוקים עקב עיגול‬
‫התוצאות‪ .‬אחרי מספר שעות כבר לא זיהה מטרות‪.‬‬
‫‪ ‬באג ה'פנטיום'‬
‫‪‬‬
‫‪‬‬
‫חישוב שגוי של חלוקת ‪floating point‬‬
‫מעריכים שעלה לאינטל ‪$400 M‬‬
‫– ‪– 27‬‬