1 / 46

Integers

Integers. נושאים: קידוד מספרים שלמים: signed & unsigned המשמעות לכתיבת תוכניות. חידות ב - C. מחשב מבוסס 32 סיביות עבור כל אחד מהביטויים הבאים ב – C , ציין אם הוא נכון תמיד (עבור כל ערך). x < 0  ((x*2) < 0) ux >= 0 x & 7 == 7  (x<<30) < 0 ux > -1 x > y  -x < -y

abbott
Download Presentation

Integers

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Integers • נושאים: • קידוד מספרים שלמים: signed & unsigned • המשמעות לכתיבת תוכניות • ...

  2. חידות ב - C • מחשב מבוסס 32 סיביות • עבור כל אחד מהביטויים הבאים ב – C, ציין אם הוא נכון תמיד (עבור כל ערך). • x < 0  ((x*2) < 0) • ux >= 0 • x & 7 == 7  (x<<30) < 0 • ux > -1 • x > y  -x < -y • x * x >= 0 • x > 0 && y > 0  x + y > 0 • x >= 0  -x <= 0 • x <= 0  -x >= 0 Initialization int x = foo(); int y = bar(); unsigned ux = x; unsigned uy = y;

  3. קידוד Integers • C תומך במספר הגדרות ל Integers: • יש הבדל בין ה'תקן' של C (מובטח לכל מהדר שתומך בתקן) לבין מה שמהדרים ומחשבים תומכים בפועל. • C Data Type Intel IA32 טווח • int 4 -32768 ... 32767 • unsigned int 4 0 ... 65535 • long int 4 -2,147,483,648 ... 2,147,483,647 • unsigned long 4 0 ... 4,294,967,295 • short 2 -32768 ... 32767 • unsigned short 2 0 ... 63535 • (במחשבים מסוימים Int מנצל את כל ה 32 סיביות) מנצל רק 2 בתים מתוך 4

  4. קידוד • כיצד נקודד מספר שלם בעזרת וקטור ביטים ? • תלוי אם הוא signed / unsigned • אם הוא unsigned הקידוד הוא פשוט המספר בבסיס 2 Binary to unsigned

  5. קידוד unsigned • המספר הנמוך ביותר שניתן לייצג: • 000....0 = 0 ומסומן ב UMin • המספר הגבוה ביותר שניתן לייצג:111....1 = 2w-1 ומסומן בUMax

  6. Binary to Two’s complement Sign Bit קידוד signed • מספר אפשרויות קידוד. האפשרות הפשוטה ביותר:הסיבית השמאלית מציינת אם המספר הוא חיובי או שלילי. • חסרונות: • ייצוג נפרד ל 0 ול -0. • קשה יותר (יחסית לאלטרנטיבה שנראה) לבצע פעולות אריתמטיות שונות. • האלטרנטיבה שרב המחשבים משתמשים בה נקראת 2’s complement

  7. מעבר ל 2-s complement • אם x הוא מספר חיובי, אז ניתן לקבל את –x על ידי ~x + 1. • כך אכן מתקבל ש x + -x = 0. • דוגמה • x = 01100 • כדי לקבל את –x תחילה נחשב את ~x: • 10011 • עכשיו נוסיף 1: • 10100 • אכן קיבלנו ש: • 01100 + • 10100 • 00000

  8. 0101+ 1101 0010 0101+ 1011 0000 עם 2’s-complement קל יותר לחבר • בשיטת סיבית שמאלית = סיבית סימן: • x = 0101 • -x = 1101 • חיבור פשוט, פשוט לא עובד. • בשיטת 2’s complement: • x = 0101 • -x = 1011

  9. דוגמה נוספת • סיבית הסימן מוסיפה מספר שלילי גדול ( -215 = -32768) short int x = 15213; short int y = -15213;

  10. המשך דוגמה x = 15213: 00111011 01101101 y = -15213: 11000100 10010011

  11. קידוד signed עם 2’s complement • המספר הנמוך ביותר שניתן לייצג: • 1000....0 = -2w-1 ומסומן ב TMin • המספר הגבוה ביותר שניתן לייצג: • 011....1 = 2w-1 -1 ומסומן בTMax

  12. חידה: מה הייצוג של -1 ? ייצוג ערכים ערכים עבור w = 16

  13. ערכי מינ'/מקס' משתנים עם רוחב המילה • נשים לב: • |TMin | = TMax + 1 • טווח לא סימטרי • UMax = 2 * TMax + 1 • כשכותבים תוכנית ב – C : • #include <limits.h> • מגדיר קבועים: • ULONG_MAX • LONG_MAX • LONG_MIN • ערכים אלה תלויים במחשב ובמהדר

  14. X B2U(X) B2T(X) 0000 0 0 0001 1 1 0010 2 2 0011 3 3 0100 4 4 0101 5 5 0110 6 6 0111 7 7 1000 8 –8 1001 9 –7 1010 10 –6 1011 11 –5 1100 12 –4 1101 13 –3 1110 14 –2 1111 15 –1 ערכים של signed & unsigned • אותו קידוד עבור מספרים לא-שליליים. • כל וקטור ביטים מייצג מספר שלם ייחודי ולהפך

  15. המרת טיפוס (Casting) מ sig. ל uns. • המרת טיפוסים ב -C • תוצאה • הייצוג (וקטור הביטים) אינו משתנה! • ערכים חיוביים נשארים: • ux = 15213 • מספרים שליליים משתנים למספרים חיוביים (גדולים): • uy = 50323 short int x = 15213; unsigned short int ux = (unsigned short) x; short int y = -15213; unsigned short int uy = (unsigned short) y;

  16. w–1 0 + - + + + + • • • • • • + + + + + + ux - x +2w–1 – –2w–1 = 2*2w–1 = 2w המרת טיפוס (Casting) מ sig. ל uns. • מה בעצם מתקבל ? הורד ערך שלילי ההבדל בערך בגלל casting הוסף ערך חיובי

  17. המרת טיפוס (Casting) מ sig. ל uns • uy = y + 2 * 32768= y + 65536

  18. Signed vs. Unsigned ב - C • קבועים • כבררת מחדל נחשבים signed. ניתן לסמנם כ uns אם מצמידים להם u : 0U, 4294967259U • המרות (Casting) • המרה מפורשת. int tx, ty; unsigned ux, uy; tx = (int) ux; uy = (unsigned) ty; • המרה לא מפורשת דרך השמות וקריאות לפונקציות: tx = ux; uy = ty;

  19. הפתעות... • ביטויים מעורבים • בביטויים מעורבים (כולל פרדיקטים:<, >, ==,...), signed הופך להיות Unsigned • דוגמאות עבור W = 32 • Constant1 Constant2 Relation Evaluation 0 0U -1 0 -1 0U 2147483647 -2147483648 2147483647U -2147483648 -1 -2 (unsigned) -1 -2 2147483647 2147483648U 2147483647 (int) 2147483648U 0 0U == unsigned -1 0 < signed -1 0U > unsigned 2147483647 -2147483648 > signed 2147483647U -2147483648 < unsigned -1 -2 > signed (unsigned) -1 -2 > unsigned 2147483647 2147483648U < unsigned 2147483647 (int) 2147483648U > signed Tmin Tmax

  20. הפתעות • אמת או שקר: • -1u > -2 • מה הערך של -1u ? • נוכל לבדוק על ידי השורה הבאה: • printf(“%u”,-1u) • נסו בבית...

  21. UMax UMax – 1 TMax + 1 TMax TMax Unsigned Range 0 0 2’s Comp. Range –1 –2 TMin הסבר • 2’s Comp.  Unsigned • מספר שלילי ==> מספר חיובי גבוה

  22. w X • • • • • • X • • • • • • w k הרחבה (Sign Extension) • המטרה • בהינתן signed int ברוחב w, המר אותו ל signed int ברוחב w + k שמייצג אותו ערך. • הכלל: • הוסף k עותקים של ה sign bit • X = xw–1 ,…, xw–1 , xw–1 , xw–2 ,…, x0 k copies of MSB

  23. Decimal Hex Binary 15213 x 3B 6D 00111011 01101101 15213 ix 00 00 3B 6D 00000000 00000000 00111011 01101101 -15213 y C4 93 11000100 10010011 -15213 iy FF FF C4 93 11111111 11111111 11000100 10010011 דוגמה להרחבה short int x = 15213; int ix = (int) x; short int y = -15213; int iy = (int) y; • C מבצע הרחבות מסוג זה באופן אוטומטי.

  24. w X - • • • X - + • • • w+1 נכונות • באינדוקציה על k • צעד האינדוקציה: נרחיב בסיבית אחת • נשים לב:–2w–1 = –2w +2w–1 • נסתכל על המשקל של הסיביות החשובות (משמאל): X–2w–1xw–1 X–2wxw–1+ 2w–1xw–1 = –2w–1xw–1

  25. -1 x 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 + ~x 0 1 1 0 0 0 1 0 חישובים: שלילה • טענה: השוויון הבא מתקיים ב 2’s complement: ~x + 1 == -x • מדוע? • ~x + x == 1111…112 == -1 • הוספה: • ~x + x + (-x + 1) == -1 + (-x + 1) • ~x + 1 == -x

  26. דוגמאות x = 15213 0

  27. • • • • • • • • • • • • חיבור ב unsigned u • מימוש של 'אריתמטיקה מודולרית' s = UAddw(u , v) = u + v mod 2w Operands: w bits + v True Sum: w+1 bits u + v Discard Carry: w bits UAddw(u , v)

  28. חיבור ints Add4(u , v) • u, v - משתנים בני 4 סיביות • הסכום האמיתי:Add4(u , v) • התוצאה גדלה ליניארית עם uv • יוצר 'משטח' v u

  29. 2w+1 2w 0 כשהמשתנים הם unsigned גלישה • חוזר להתחלה... • אם הסכום האמיתי גדול מ 2w • לא יותר מפעם אחת UAdd4(u , v) True Sum גלישה v סכום מודולרי u

  30. תכונות מתמטיות • סגור תחת חיבור 0   UAddw(u , v)     2w –1 • קומוטטיבי UAddw(u , v)  =   UAddw(v , u) • אסוציאטיבי UAddw(t, UAddw(u , v))  =   UAddw(UAddw(t, u ), v) • תפקידו של ה - 0 UAddw(u , 0)  =  u • קיים אלמנט משלים: • Let UCompw (u )  = 2w – u UAddw(u , UCompw (u ))  =  0

  31. • • • • • • • • • • • • חיבור 2’s Complement u • TAdd and UAdd פועלות זהה ברמת הביטים • חיבור ב – C: int s, t, u, v; s = (int) ((unsigned) u + (unsigned) v); t = u + v • נקבל s == t Operands: w bits + v True Sum: w+1 bits u + v Discard Carry: w bits TAddw(u , v)

  32. u + v + 2w u + v < Tminw(NegOver) u + v Tminw· u + v · Tmaxw u + v – 2w u + v > Tmaxw(PosOver) Taddw(u,v) = אפיון של TAdd • פונקציונאליות • הסכום האמיתי דורש w+1 סיביות • הורד את ה - MSB • התייחס למה שנשאר כ int המיוצג ב – 2’s complement • למשל: עבור w = 4 מתקבל -8 + -1 = 7. 1000 + 1111 0111

  33. חיבור ב 2’s complement • ערכים • 4 סיביות • טווח:מ -8 עד +7 • גלישה • אם sum  2w–1 • נהיה שלילי • לא יותר מפעם אחת • אם sum < –2w–1 • נהיה חיובי • לא יותר מפעם אחת NegOver TAdd4(u , v) v u PosOver

  34. כיצד נזהה גלישה ? • מטרה • בהינתן s = TAddw(u , v) • קבע האם s =Addw(u , v) • דוגמה int s, u, v; s = u + v; • טענה • גלישה אם u, v < 0, s 0 (NegOver) u, v 0, s < 0 (PosOver) ovf = (u<0 == v<0) && (u<0 != s<0);

  35. מכפלה • טווחים • Unsigned: 0 ≤ x * y ≤ (2w – 1) 2 = 22w – 2w+1 + 1 • Up to 2w bits • Two’s complement min: x * y ≥ (–2w–1)*(2w–1–1) = –22w–2 + 2w–1 • Up to 2w–1 bits • Two’s complement max:x * y ≤ (–2w–1) 2 = 22w–2 • Up to 2w bits, but only for (TMinw)2 • תיגרם גלישה. התוצאה: בשקף הבא. • כיצד נחשב 'בדיוק' ? • דורש הקצאה דינמית של זיכרון • ישנן חבילות תוכנה לחישוב מדויק (“arbitrary precision” arithmetic packages) • GNU Multiple Precision (GMP) • http://gmplib.org/

  36. • • • • • • • • • • • • • • • מכפלה של unsigned ב - C u • מכפלה סטנדרטית • מתעלם מ w הביטים משמאל. • למעשה מחשב מכפלה ב modular arithmetic UMultw(u , v) = u · v mod 2w Operands: w bits * v True Product: 2*w bits u · v UMultw(u , v) Discard w bits: w bits

  37. מכפלה של Signed • מכפלת מספרים המיוצגים ב 2’s complement int x, y; int p = x * y; • חשב תוצאת מכפלה של שני מספרים x,y ברוחב w. • הורד ביטים משמאל עד קבלת תוצאה ברוחב w.p = TMultw(x, y) • (כלומר, החישוב זהה למקרה הקודם)

  38. השוואה בין שני המקרים • Unsigned Multiplication unsigned ux = (unsigned) x; unsigned uy = (unsigned) y; unsigned up = ux * uy • Two’s Complement Multiplication int x, y; int p = x * y; • היחס ביניהם • נותן בדיוק אותה תוצאה ברמת הביטים • מתקיים היחס:up == (unsigned) p

  39. • • • k u • • • Operands: w bits * 2k 0 ••• 0 1 0 ••• 0 0 True Product: w+k bits u · 2k 0 ••• 0 0 UMultw(u , 2k) ••• 0 ••• 0 0 Discard k bits: w bits TMultw(u , 2k) מכפלה בחזקות של 2 עם shift • נשים לב • u << k gives u * 2k • הן ב signed והן ב unsigned • דוגמאות • u << 3 == u * 8 • (u << 5) – (u << 3) == u * 24 • ברוב המחשבים הכפלה איטית בהרבה לעומת shift ו add. • בדר"כ המהדר יודע לבצע את ההתמרה ל Shift בכוחות עצמו.

  40. ••• ••• חלוקה בחזקות של 2 עם Shift • u >> k gives  u / 2k  • כלומר במספרים שליליים התוצאה תעוגל כלפי מטה, לא כלפי 0. • בדוגמה להלן נניח unsigned ולכן נשתמש ב logical shift k u Binary Point ••• Operands: / 2k 0 ••• 0 1 0 ••• 0 0 Division: u / 2k . 0 ••• ••• Result: u / 2k  0 ••• ••• עכשיו נניח x = -9

  41. תשובות לחידות ב - C int x = foo(); int y = bar(); unsigned ux = x; unsigned uy = y; • נניח מחשב עם 32 סיביות וקידוד 2’s complement. • x < 0  ((x*2) < 0) False: TMin • ux >= 0 True: 0 = UMin • x & 7 == 7  (x<<30) < 0 True: x1 = 1 • ux > -1 False: 0 • x > y  -x < -y False: -1, TMin • x * x >= 0 False: 30426 • x > 0 && y > 0  x + y > 0 False: TMax, TMax • x >= 0  -x <= 0 True: –TMax < 0 • x <= 0  -x >= 0 False: TMin • x < 0  ((x*2) < 0) • ux >= 0 • x & 7 == 7  (x<<30) < 0 • ux > -1 • x > y  -x < -y • x * x >= 0 • x > 0 && y > 0  x + y > 0 • x >= 0  -x <= 0 • x <= 0  -x >= 0

  42. ביתר פרוט... • x & 7 == 7  (x<<30) < 0 • מצד שמאל אנחנו יודעים:3 הסיביות הימניות הן 1. • אחרי הזזה שמאלה ב – 30 מקומות, ה sign-bit חייב להיות 1, כלומר מספר שלילי. • לדוגמה, נניחx = 15. • האם מקייםx & 7 == 7 ? • אחרי הזזה 30 צעדים שמאלה: 11000000..... • (קרוב ל Tmin)

  43. ביתר פרוט... • ux > -1 • המרת טיפוס אוטומטית ל unsigned. • ייצוג של -1: • 1111....111 • אחרי המרה ל unsigned: Umax • 4,294,967,295 • כלומר התשובה היא לא: לא מתקיים ux > -1.

  44. ביתר פרוט... • x >= 0  -x <= 0 • נזכור ש |Tmax| < |Tmin| • לכן כאן התשובה היא כן • x <=0  -x >= 0 • וכאן יש לנו גלישה. לכן התשובה היא לא.

  45. מתי נשתמש ב Unsigned? • לא להשתמש רק בגלל שאין צורך בשליליים! • קיימים מהדרי C שזה גורם להם ליצור קוד פחות יעיל • קל לעשות טעויות (כפי שראינו!) • אז מתי כן להשתמש ב unsigned? • כשצריך טווח גדול יותר של מספרים חיוביים • יישומים שונים מסתמכים על modular arithmetic (מסתמכים על הערך אחרי הגלישה) • לעתים משתמשים ב Int כאוסף של דגלים. • למשל, קיבוץ של 6 דגלים:011001 • פונקציות סטנדטיות לעתים מחזירות unsigned. למשל size() (מחזיר size_t שזה בעצם unsigned). • vector v; • unsigned s = v.size();

  46. מתי נשתמש ב Unsigned? • לא להשתמש רק בגלל שאין צורך בשליליים! • קיימים מהדרי C שזה גורם להם ליצור קוד פחות יעיל • קל לעשות טעויות: • 1. float sum_elements(float a[], unsigned length) { int i; float result = 0; for (i = 0; i <= length -1 ; i++) result += a[i]; return result; } • 2. unsigned int i; for (i = cnt-2; i >= 0; i--) a[i] += a[i+1];

More Related