Transcript C3_integers

‫‪Integers‬‬
‫נושאים‪:‬‬
‫‪ ‬קידוד מספרים שלמים‪signed & unsigned :‬‬
‫‪ ‬המשמעות לכתיבת תוכניות‬
‫‪... ‬‬
C - ‫חידות ב‬
‫ סיביות‬32 ‫מחשב מבוסס‬
‫ ציין אם הוא נכון תמיד (עבור כל‬,C – ‫עבור כל אחד מהביטויים הבאים ב‬
.)‫ערך‬

•
x < 0
•
ux >= 0
•
x & 7 == 7
•
ux > -1
•
x > y
unsigned ux = x;
•
x * x >= 0
unsigned uy = y;
•
x > 0 && y > 0 
•
x >= 0

-x <= 0
•
x <= 0

-x >= 0
Initialization
int x = foo();
int y = bar();
–2–

((x*2) < 0)



(x<<30) < 0
-x < -y
x + y > 0
‫קידוד ‪Integers‬‬
‫‪ C ‬תומך במספר הגדרות ל ‪:Integers‬‬
‫‪ ‬יש הבדל בין ה'תקן' של ‪( C‬מובטח לכל מהדר שתומך בתקן) לבין‬
‫מה שמהדרים ומחשבים תומכים בפועל‪.‬‬
‫מנצל רק ‪2‬‬
‫בתים מתוך ‪4‬‬
‫‪Intel IA32‬‬
‫טווח‬
‫‪4‬‬
‫‪-32768 ... 32767‬‬
‫‪4‬‬
‫‪0 ... 65535‬‬
‫‪4‬‬
‫‪-2,147,483,648 ... 2,147,483,647‬‬
‫‪4‬‬
‫‪0 ... 4,294,967,295‬‬
‫‪2‬‬
‫‪-32768 ... 32767‬‬
‫‪2‬‬
‫‪0 ... 63535‬‬
‫‪C Data Type‬‬
‫‪ int‬‬
‫‪ unsigned int‬‬
‫‪ long int‬‬
‫‪ unsigned long‬‬
‫‪ short‬‬
‫‪ unsigned short‬‬
‫‪‬‬
‫‪( ‬במחשבים מסוימים ‪ Int‬מנצל את כל ה ‪ 32‬סיביות)‬
‫–‪–3‬‬
‫קידוד‬
‫‪ ‬כיצד נקודד מספר שלם בעזרת וקטור ביטים ?‬
‫‪ ‬תלוי אם הוא ‪signed / unsigned‬‬
‫‪ ‬אם הוא ‪ unsigned‬הקידוד הוא פשוט המספר בבסיס ‪2‬‬
‫‪i‬‬
‫‪w 1‬‬
‫‪xi  2‬‬
‫‪‬‬
‫‪‬‬
‫) ‪B 2U ( X‬‬
‫‪i0‬‬
‫‪Binary to‬‬
‫‪unsigned‬‬
‫–‪–4‬‬
‫קידוד ‪unsigned‬‬
‫‪ ‬המספר הנמוך ביותר שניתן לייצג‪:‬‬
‫‪ 000....0 = 0‬ומסומן ב ‪UMin‬‬
‫‪ ‬המספר הגבוה ביותר שניתן לייצג‪:‬‬
‫‪ 111....1 = 2w-1‬ומסומן ב ‪UMax‬‬
‫–‪–5‬‬
‫קידוד ‪signed‬‬
‫‪ ‬מספר אפשרויות קידוד‪ .‬האפשרות הפשוטה ביותר‪ :‬הסיבית‬
‫השמאלית מציינת אם המספר הוא חיובי או שלילי‪.‬‬
‫‪ ‬חסרונות‪:‬‬
‫‪‬‬
‫‪‬‬
‫ייצוג נפרד ל ‪ 0‬ול ‪.-0‬‬
‫קשה יותר (יחסית לאלטרנטיבה שנראה) לבצע פעולות אריתמטיות‬
‫שונות‪.‬‬
‫‪ ‬האלטרנטיבה שרב המחשבים משתמשים בה נקראת‬
‫‪2’s complement‬‬
‫‪i‬‬
‫‪w2‬‬
‫‪ xi  2‬‬
‫‪‬‬
‫‪w 1‬‬
‫‪ x w 1  2‬‬
‫‪‬‬
‫) ‪B 2T ( X‬‬
‫‪i0‬‬
‫‪Sign‬‬
‫‪Bit‬‬
‫‪Binary to‬‬
‫‪Two’s‬‬
‫‪complement‬‬
‫–‪–6‬‬
‫מעבר ל ‪2-s complement‬‬
‫‪ ‬אם ‪ x‬הוא מספר חיובי‪ ,‬אז ניתן לקבל את ‪ –x‬על ידי ‪.~x + 1‬‬
‫‪‬‬
‫כך אכן מתקבל ש ‪.x + -x = 0‬‬
‫דוגמה‬
‫‪x = 01100‬‬
‫כדי לקבל את ‪ –x‬תחילה נחשב את ‪:~x‬‬
‫‪10011‬‬
‫עכשיו נוסיף ‪:1‬‬
‫‪10100‬‬
‫אכן קיבלנו ש‪:‬‬
‫‪01100 +‬‬
‫‪10100‬‬
‫‪00000‬‬
‫–‪–7‬‬
‫עם ‪ 2’s-complement‬קל יותר לחבר‬
‫בשיטת סיבית שמאלית = סיבית סימן‪:‬‬
‫‪x = 0101‬‬
‫‪0101+‬‬
‫‪-x = 1101‬‬
‫‪1101‬‬
‫חיבור פשוט‪ ,‬פשוט לא עובד‪.‬‬
‫‪0010‬‬
‫בשיטת ‪:2’s complement‬‬
‫‪x = 0101‬‬
‫‪0101+‬‬
‫‪-x = 1011‬‬
‫‪1011‬‬
‫‪0000‬‬
‫–‪–8‬‬
‫דוגמה נוספת‬
‫;‪short int x = 15213‬‬
‫;‪short int y = -15213‬‬
‫‪Binary‬‬
‫‪00111011 01101101‬‬
‫‪11000100 10010011‬‬
‫‪Decimal‬‬
‫‪15213‬‬
‫‪-15213‬‬
‫‪x‬‬
‫‪y‬‬
‫‪ ‬סיבית הסימן מוסיפה מספר שלילי גדול )‪( -215 = -32768‬‬
‫–‪–9‬‬
‫המשך דוגמה‬
x =
y =
W e ig h t
– 10 –
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
-3 2 7 6 8
Sum
15213: 00111011 01101101
-15213: 11000100 10010011
15213
1
1
0
0
1
4
1
8
0
0
1
32
1
64
0
0
1
256
1
512
0
0
1
2048
1
4096
1
8192
0
0
0
0
15213
-1 5 2 1 3
1
1
1
2
0
0
0
0
1
16
0
0
0
0
1
128
0
0
0
0
1
1024
0
0
0
0
0
0
1
16384
1
-3 2 7 6 8
-1 5 2 1 3
‫קידוד ‪ signed‬עם ‪2’s complement‬‬
‫‪‬המספר הנמוך ביותר שניתן לייצג‪:‬‬
‫‪ 1000....0 = -2w-1‬ומסומן ב ‪TMin‬‬
‫‪‬המספר הגבוה ביותר שניתן לייצג‪:‬‬
‫‪ 011....1 = 2w-1 -1‬ומסומן ב ‪TMax‬‬
‫– ‪– 11‬‬
‫ייצוג ערכים‬
? -1 ‫ מה הייצוג של‬:‫ חידה‬
w = 16 ‫ערכים עבור‬
UMax
TMax
TMin
-1
0
– 12 –
D e cim a l
65535
32767
-3 2 7 6 8
-1
0
Hex
FF FF
7F FF
80 00
FF FF
00 00
B in a ry
11111111 11111111
01111111 11111111
10000000 00000000
11111111 11111111
00000000 00000000
‫ערכי מינ'‪/‬מקס' משתנים עם רוחב המילה‬
‫‪W‬‬
‫‪64‬‬
‫‪1 8 ,4 4 6 ,7 4 4 ,0 7 3 ,7 0 9 ,5 5 1 ,6 1 5‬‬
‫‪9 ,2 2 3 ,3 7 2 ,0 3 6 ,8 5 4 ,7 7 5 ,8 0 7‬‬
‫‪-9 ,2 2 3 ,3 7 2 ,0 3 6 ,8 5 4 ,7 7 5 ,8 0 8‬‬
‫‪32‬‬
‫‪4 ,2 9 4 ,9 6 7 ,2 9 5‬‬
‫‪2 ,1 4 7 ,4 8 3 ,6 4 7‬‬
‫‪-2 ,1 4 7 ,4 8 3 ,6 4 8‬‬
‫כשכותבים תוכנית ב – ‪: C‬‬
‫‪‬‬
‫‪‬‬
‫>‪#include <limits.h‬‬
‫מגדיר קבועים‪:‬‬
‫‪ULONG_MAX ‬‬
‫‪LONG_MAX ‬‬
‫‪LONG_MIN ‬‬
‫‪‬‬
‫‪16‬‬
‫‪6 5 ,5 3 5‬‬
‫‪3 2 ,7 6 7‬‬
‫‪-3 2 ,7 6 8‬‬
‫‪8‬‬
‫‪255‬‬
‫‪127‬‬
‫‪-1 2 8‬‬
‫‪U M ax‬‬
‫‪TM ax‬‬
‫‪T M in‬‬
‫נשים לב‪:‬‬
‫‪‬‬
‫| ‪TMax + 1= |TMin‬‬
‫‪ ‬טווח לא סימטרי‬
‫‪‬‬
‫‪2 * TMax + 1 = UMax‬‬
‫ערכים אלה תלויים במחשב ובמהדר‬
‫– ‪– 13‬‬
‫ערכים של ‪signed & unsigned‬‬
‫‪ ‬אותו קידוד עבור מספרים לא‪-‬‬
‫שליליים‪.‬‬
‫‪ ‬כל וקטור ביטים מייצג מספר‬
‫שלם ייחודי ולהפך‬
‫)‪B2T(X‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪–8‬‬
‫‪–7‬‬
‫‪–6‬‬
‫‪–5‬‬
‫‪–4‬‬
‫‪–3‬‬
‫‪–2‬‬
‫‪–1‬‬
‫)‪B2U(X‬‬
‫‪0‬‬
‫‪1‬‬
‫‪2‬‬
‫‪3‬‬
‫‪4‬‬
‫‪5‬‬
‫‪6‬‬
‫‪7‬‬
‫‪8‬‬
‫‪9‬‬
‫‪10‬‬
‫‪11‬‬
‫‪12‬‬
‫‪13‬‬
‫‪14‬‬
‫‪15‬‬
‫‪X‬‬
‫‪0000‬‬
‫‪0001‬‬
‫‪0010‬‬
‫‪0011‬‬
‫‪0100‬‬
‫‪0101‬‬
‫‪0110‬‬
‫‪0111‬‬
‫‪1000‬‬
‫‪1001‬‬
‫‪1010‬‬
‫‪1011‬‬
‫‪1100‬‬
‫‪1101‬‬
‫‪1110‬‬
‫‪1111‬‬
‫– ‪– 14‬‬
‫המרת טיפוס (‪ )Casting‬מ ‪ sig.‬ל ‪uns.‬‬
‫המרת טיפוסים ב ‪C -‬‬
‫‪short int‬‬
‫;‪x = 15213‬‬
‫;‪unsigned short int ux = (unsigned short) x‬‬
‫‪short int‬‬
‫;‪y = -15213‬‬
‫;‪unsigned short int uy = (unsigned short) y‬‬
‫תוצאה‬
‫‪‬‬
‫‪‬‬
‫הייצוג (וקטור הביטים) אינו משתנה!‬
‫ערכים חיוביים נשארים‪:‬‬
‫‪ux = 15213 ‬‬
‫‪‬‬
‫מספרים שליליים משתנים למספרים חיוביים (גדולים)‪:‬‬
‫‪uy = 50323 ‬‬
‫– ‪– 15‬‬
‫המרת טיפוס (‪ )Casting‬מ ‪ sig.‬ל ‪uns.‬‬
‫מה בעצם מתקבל ?‬
‫‪x 0‬‬
‫‪x 0‬‬
‫‪x‬‬
‫‪‬‬
‫‪w‬‬
‫‪x  2‬‬
‫‪‬‬
‫‪ux‬‬
‫‪0‬‬
‫‪+++‬‬
‫• • •‬
‫‪w–1‬‬
‫‪ux + + +‬‬
‫‪+++‬‬
‫• • •‬
‫‪x‬‬
‫‪-++‬‬
‫‪-‬‬
‫‪+2w–1 – –2w–1 = 2*2w–1 = 2w‬‬
‫ההבדל בערך‬
‫בגלל ‪casting‬‬
‫הורד ערך שלילי‬
‫הוסף ערך חיובי‬
‫– ‪– 16‬‬
uns ‫ ל‬sig. ‫) מ‬Casting( ‫המרת טיפוס‬
W e ig h t
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
Sum
-1 5 2 1 3
1
1
1
2
0
0
0
0
1
16
0
0
0
0
1
128
0
0
0
0
1
1024
0
0
0
0
0
0
1
16384
1
-3 2 7 6 8
-1 5 2 1 3
y + 65536=
– 17 –
50323
1
1
1
2
0
0
0
0
1
16
0
0
0
0
1
128
0
0
0
0
1
1024
0
0
0
0
0
0
1
16384
1
32768
50323
y + 2 * 32768= uy

‫‪ Signed vs. Unsigned‬ב ‪C -‬‬
‫קבועים‬
‫‪‬‬
‫כבררת מחדל נחשבים ‪ .signed‬ניתן לסמנם כ ‪ uns‬אם מצמידים להם ‪: u‬‬
‫‪0U, 4294967259U‬‬
‫המרות (‪)Casting‬‬
‫‪‬‬
‫המרה מפורשת‪.‬‬
‫;‪ty‬‬
‫;‪uy‬‬
‫;‪ux‬‬
‫;‪ty‬‬
‫‪‬‬
‫‪int tx,‬‬
‫‪unsigned ux,‬‬
‫)‪tx = (int‬‬
‫)‪uy = (unsigned‬‬
‫המרה לא מפורשת דרך השמות וקריאות לפונקציות‪:‬‬
‫;‪tx = ux‬‬
‫;‪uy = ty‬‬
‫– ‪– 18‬‬
...‫הפתעות‬
‫ביטויים מעורבים‬
‫ הופך להיות‬signed ,)<, >, ==,...:‫ בביטויים מעורבים (כולל פרדיקטים‬
Unsigned
W = 32 ‫ דוגמאות עבור‬
Constant1
Tmax
– 19 –
00
-1
-1
-1
-1
2147483647
2147483647
2147483647U
2147483647U
-1
-1
(unsigned) -1
-1
(unsigned)
2147483647
2147483647
2147483647
2147483647
Constant2
Relation Evaluation
0U
0U
00
Tmin
0U
0U
-2147483648
-2147483648
-2147483648
-2147483648
-2
-2
-2
-2
2147483648U
2147483648U
(int) 2147483648U
2147483648U
(int)
==
<
>
>
<
>
>
<
>
unsigned
signed
unsigned
signed
unsigned
signed
unsigned
unsigned
signed
‫הפתעות‬
‫‪ ‬אמת או שקר‪:‬‬
‫‪ -1u > -2‬‬
‫‪ ‬מה הערך של ‪? -1u‬‬
‫‪ ‬נוכל לבדוק על ידי השורה הבאה‪:‬‬
‫)‪ printf(“%u”,-1u‬‬
‫נסו בבית‪...‬‬
‫– ‪– 20‬‬
‫הסבר‬
2’s Comp.  Unsigned
‫מספר שלילי ==> מספר חיובי גבוה‬
TMax
2’s Comp.
Range
– 21 –
0
–1
–2
TMin

UMax
UMax – 1
TMax + 1
TMax
0
Unsigned
Range
)Sign Extension( ‫הרחבה‬
‫המטרה‬
w + k ‫ ברוחב‬signed int ‫ המר אותו ל‬,w ‫ ברוחב‬signed int ‫בהינתן‬
.‫שמייצג אותו ערך‬

:‫הכלל‬

sign bit ‫ עותקים של ה‬k ‫הוסף‬
X  = xw–1 ,…, xw–1 , xw–1 , xw–2 ,…, x0
w
k copies of MSB
X
• • •
• • •
X
– 22 –
• • •
k
• • •
w

‫דוגמה להרחבה‬
short int x = 15213;
int
ix = (int) x;
short int y = -15213;
int
iy = (int) y;
x
ix
y
iy
Decimal
Hex
15213
3B
15213 00 00 3B
-15213
C4
-15213 FF FF C4
6D
6D
93
93
Binary
00111011
00000000 00000000 00111011
11000100
11111111 11111111 11000100
01101101
01101101
10010011
10010011
.‫ מבצע הרחבות מסוג זה באופן אוטומטי‬C
– 23 –

‫נכונות‬
‫באינדוקציה על ‪k‬‬
‫‪‬‬
‫צעד האינדוקציה‪ :‬נרחיב בסיבית אחת‬
‫‪w‬‬
‫• • •‬
‫‪-‬‬
‫• • •‬
‫‪- +‬‬
‫‪X‬‬
‫‪X‬‬
‫‪w+1‬‬
‫‪‬‬
‫‪‬‬
‫נשים לב‪–2w–1 = –2w +2w–1 :‬‬
‫נסתכל על המשקל של הסיביות החשובות (משמאל)‪:‬‬
‫‪–2w–1 xw–1‬‬
‫=‬
‫‪–2w–1 xw–1‬‬
‫‪–2w xw–1 + 2w–1 xw–1‬‬
‫‪X‬‬
‫‪X‬‬
‫– ‪– 24‬‬
‫חישובים‪ :‬שלילה‬
‫‪ ‬טענה‪ :‬השוויון הבא מתקיים ב ‪:2’s complement‬‬
‫‪~x + 1 == -x‬‬
‫‪ ‬מדוע?‬
‫‪‬‬
‫‪~x + x == 1111…112 == -1‬‬
‫‪1001 1101‬‬
‫‪x‬‬
‫‪0110 0010‬‬
‫‪+ ~x‬‬
‫‪1111 1111‬‬
‫‪-1‬‬
‫הוספה‪:‬‬
‫)‪== -1 + (-x + 1‬‬
‫‪== -x‬‬
‫)‪~x + x + (-x + 1‬‬
‫‪~x + 1‬‬
‫‪‬‬
‫‪‬‬
‫– ‪– 25‬‬
‫דוגמאות‬
x = 15213
x
~x
~x+1
y
D e cim a l
15213
-1 5 2 1 4
-1 5 2 1 3
-1 5 2 1 3
Hex
3B 6D
C4 92
C4 93
C4 93
B in a ry
00111011 01101101
11000100 10010010
11000100 10010011
11000100 10010011
0
0
~0
~0+1
– 26 –
D e cim a l
0
-1
0
Hex
00 00
FF FF
00 00
B in a ry
00000000 00000000
11111111 11111111
00000000 00000000
unsigned ‫חיבור ב‬
u
• • •
v
• • •
u+v
• • •
UAddw(u , v)
• • •
Operands: w bits
+
True Sum: w+1 bits
Discard Carry: w bits
'‫מימוש של 'אריתמטיקה מודולרית‬
u + v mod 2w=
UAdd
– 27 –
UAddw(u , v)= s
w (u, v )

 u  v

w
u  v  2
uv2
w
uv2
w
‫חיבור ‪ints‬‬
‫)‪Add4(u , v‬‬
‫‪‬‬
‫‪Integer Addition‬‬
‫‪‬‬
‫‪32‬‬
‫‪28‬‬
‫‪‬‬
‫‪24‬‬
‫‪20‬‬
‫‪16‬‬
‫‪14‬‬
‫‪‬‬
‫‪ - u, v‬משתנים בני ‪4‬‬
‫סיביות‬
‫הסכום האמיתי‪:‬‬
‫)‪Add4(u , v‬‬
‫התוצאה גדלה ליניארית‬
‫עם ‪u v‬‬
‫יוצר 'משטח'‬
‫‪12‬‬
‫‪12‬‬
‫‪10‬‬
‫‪8‬‬
‫‪8‬‬
‫‪v‬‬
‫‪4‬‬
‫‪6‬‬
‫‪0‬‬
‫‪4‬‬
‫‪2‬‬
‫‪0‬‬
‫‪14‬‬
‫‪12‬‬
‫‪10‬‬
‫‪8‬‬
‫‪6‬‬
‫‪4‬‬
‫‪2‬‬
‫‪0‬‬
‫‪u‬‬
‫– ‪– 28‬‬
‫כשהמשתנים הם ‪unsigned‬‬
‫חוזר להתחלה‪...‬‬
‫גלישה‬
‫‪‬‬
‫)‪UAdd4(u , v‬‬
‫‪‬‬
‫אם הסכום האמיתי גדול‬
‫מ ‪2w‬‬
‫לא יותר מפעם אחת‬
‫‪16‬‬
‫‪14‬‬
‫‪12‬‬
‫גלישה‬
‫‪True Sum‬‬
‫‪2w+1‬‬
‫‪10‬‬
‫‪8‬‬
‫‪14‬‬
‫‪6‬‬
‫‪12‬‬
‫‪10‬‬
‫‪v‬‬
‫‪2w‬‬
‫‪4‬‬
‫‪8‬‬
‫‪2‬‬
‫‪6‬‬
‫‪0‬‬
‫‪4‬‬
‫‪2‬‬
‫‪0‬‬
‫‪14‬‬
‫‪12‬‬
‫‪10‬‬
‫‪8‬‬
‫‪6‬‬
‫‪4‬‬
‫‪2‬‬
‫‪0‬‬
‫סכום מודולרי‬
‫‪0‬‬
‫‪u‬‬
‫– ‪– 29‬‬
‫תכונות מתמטיות‬
‫סגור תחת חיבור‬

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
:‫קיים אלמנט משלים‬
UCompw (u ) = 2w – u
UAddw(u , UCompw (u )) = 0
 Let
– 30 –

2’s Complement ‫חיבור‬
u
• • •
v
• • •
u+v
• • •
TAddw(u , v)
• • •
Operands: w bits
+
True Sum: w+1 bits
Discard Carry: w bits
‫ פועלות זהה ברמת הביטים‬TAdd and UAdd
:C – ‫חיבור ב‬

int s, t, u, v;
s = (int) ((unsigned) u + (unsigned) v);
t = u + v
s == t ‫נקבל‬
– 31 –

‫אפיון של ‪TAdd‬‬
‫)‪u + v < Tminw (NegOver‬‬
‫‪Tminw · u + v · Tmaxw‬‬
‫)‪u + v > Tmaxw (PosOver‬‬
‫‪u + v + 2w‬‬
‫‪u+v‬‬
‫‪u + v – 2w‬‬
‫= )‪Taddw(u,v‬‬
‫פונקציונאליות‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫‪‬‬
‫הסכום האמיתי דורש ‪ w+1‬סיביות‬
‫הורד את ה ‪MSB -‬‬
‫התייחס למה שנשאר כ ‪ int‬המיוצג ב – ‪2’s complement‬‬
‫למשל‪ :‬עבור ‪ w = 4‬מתקבל ‪. -8 + -1 = 7‬‬
‫‪1000 +‬‬
‫‪1111‬‬
‫‪0111‬‬
‫– ‪– 32‬‬
‫חיבור ב ‪2’s complement‬‬
‫‪NegOver‬‬
‫ערכים‬
‫)‪TAdd4(u , v‬‬
‫‪‬‬
‫‪‬‬
‫‪8‬‬
‫‪6‬‬
‫גלישה‬
‫‪‬‬
‫‪4‬‬
‫‪0‬‬
‫‪6‬‬
‫‪-2‬‬
‫‪2‬‬
‫‪-4‬‬
‫‪0‬‬
‫‪-6‬‬
‫‪-2‬‬
‫‪v‬‬
‫‪-8‬‬
‫‪-4‬‬
‫‪-6‬‬
‫‪PosOver‬‬
‫‪-8‬‬
‫‪6‬‬
‫‪4‬‬
‫‪2‬‬
‫‪0‬‬
‫‪-2‬‬
‫‪-4‬‬
‫‪-6‬‬
‫‪-8‬‬
‫אם ‪sum  2w–1‬‬
‫‪ ‬נהיה שלילי‬
‫‪ ‬לא יותר מפעם אחת‬
‫‪2‬‬
‫‪4‬‬
‫‪ 4‬סיביות‬
‫טווח‪ :‬מ ‪ -8‬עד ‪+7‬‬
‫‪‬‬
‫אם ‪sum < –2w–1‬‬
‫‪ ‬נהיה חיובי‬
‫‪ ‬לא יותר מפעם אחת‬
‫‪u‬‬
‫– ‪– 33‬‬
? ‫כיצד נזהה גלישה‬
‫מטרה‬
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);
– 34 –

‫מכפלה‬
‫טווחים‬

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/ 
– 35 –


C - ‫ ב‬unsigned ‫מכפלה של‬
Operands: w bits
True Product: 2*w bits u · v
Discard w bits: w bits
*
u
• • •
v
• • •
• • •
• • •
• • •
UMultw(u , v)
‫מכפלה סטנדרטית‬
.‫ הביטים משמאל‬w ‫מתעלם מ‬

modular arithmetic ‫למעשה מחשב מכפלה ב‬
u · v mod 2w= UMultw(u , v)
– 36 –
‫מכפלה של ‪Signed‬‬
‫מכפלת מספרים המיוצגים ב ‪2’s complement‬‬
‫;‪int x, y‬‬
‫;‪int p = x * y‬‬
‫‪‬‬
‫חשב תוצאת מכפלה של שני מספרים ‪ x,y‬ברוחב ‪.w‬‬
‫הורד ביטים משמאל עד קבלת תוצאה ברוחב ‪p = TMultw(x, y) .w‬‬
‫‪‬‬
‫(כלומר‪ ,‬החישוב זהה למקרה הקודם)‬
‫‪‬‬
‫– ‪– 37‬‬
‫השוואה בין שני המקרים‬
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
:‫מתקיים היחס‬
– 38 –


shift ‫ עם‬2 ‫מכפלה בחזקות של‬
‫נשים לב‬
u << k gives u * 2k

unsigned ‫ והן ב‬signed ‫הן ב‬

Operands: w bits
True Product: w+k bits
*
u · 2k
u
k
• • •
2k
0 ••• 0 1 0 ••• 0 0
• • •
UMultw(u , 2k)
Discard k bits: w bits
TMultw(u , 2k)
u * 8
0 ••• 0 0
‫דוגמאות‬
==
u << 3
(u << 5) – (u << 3)

.add ‫ ו‬shift ‫ברוב המחשבים הכפלה איטית בהרבה לעומת‬

u * 24
– 39 –
•••
0 ••• 0 0
==
.‫ בכוחות עצמו‬Shift ‫ בדר"כ המהדר יודע לבצע את ההתמרה ל‬

Shift ‫ עם‬2 ‫חלוקה בחזקות של‬
u >> k gives  u / 2k 

.0 ‫ לא כלפי‬,‫כלומר במספרים שליליים התוצאה תעוגל כלפי מטה‬
logical shift ‫ ולכן נשתמש ב‬unsigned ‫בדוגמה להלן נניח‬


k
u
Operands:
/
x
x >> 1
x >> 4
x >> 8
– 40 –
•••
0 •••
•••
 u / 2k 
0 •••
•••
Division
15213
7606.5
950.8125
59.4257813
10111 >> 1
Computed
15213
7606
950
59
-4.5
Binary Point
0 ••• 0 1 0 ••• 0 0
u / 2k
Division:
Result:
2k
•••
Hex
3B 6D
1D B6
03 B6
00 3B
-5 11011
.
•••
Binary
00111011 01101101
00011101 10110110
00000011 10110110
00000000 00111011
x = -9 ‫עכשיו נניח‬
C - ‫תשובות לחידות ב‬
int x = foo();
int y = bar();
unsigned ux = x;
.2’s complement ‫ סיביות וקידוד‬32 ‫נניח מחשב עם‬
unsigned uy = y;


x < 0

ux >= 0

x & 7 == 7

ux > -1

x > y

x * x >= 0

x > 0 && y > 0


x >= 0

x <= 0
– 41 –
((x*2) < 0)
False:
TMin
True:
0 = UMin
True:
x1 = 1
False:
0
False:
-1, TMin
False:
30426
x + y > 0
False:
TMax, TMax

-x <= 0
True:
–TMax < 0

-x >= 0
False:
TMin


(x<<30) < 0
-x < -y

‫ביתר פרוט‪...‬‬
‫‪(x<<30) < 0‬‬
‫‪‬‬
‫‪x & 7 == 7‬‬
‫‪ ‬מצד שמאל אנחנו יודעים‪ 3 :‬הסיביות הימניות הן ‪.1‬‬
‫‪ ‬אחרי הזזה שמאלה ב – ‪ 30‬מקומות‪ ,‬ה ‪ sign-bit‬חייב להיות ‪ ,1‬כלומר מספר שלילי‪.‬‬
‫‪ ‬לדוגמה‪ ,‬נניח ‪.x = 15‬‬
‫‪‬‬
‫האם מקיים ‪? x & 7 == 7‬‬
‫‪‬‬
‫אחרי הזזה ‪ 30‬צעדים שמאלה‪11000000.....:‬‬
‫‪‬‬
‫(קרוב ל ‪)Tmin‬‬
‫– ‪– 42‬‬
‫ביתר פרוט‪...‬‬
‫‪ux > -1‬‬
‫‪ ‬המרת טיפוס אוטומטית ל ‪.unsigned‬‬
‫‪ ‬ייצוג של ‪:-1‬‬
‫‪1111....111‬‬
‫אחרי המרה ל ‪Umax :unsigned‬‬
‫‪4,294,967,295‬‬
‫כלומר התשובה היא לא‪ :‬לא מתקיים ‪.ux > -1‬‬
‫– ‪– 43‬‬
‫ביתר פרוט‪...‬‬
‫‪-x <= 0‬‬
‫‪x >= 0 ‬‬
‫נזכור ש |‪|Tmax| < |Tmin‬‬
‫לכן כאן התשובה היא כן‬
‫‪-x >= 0‬‬
‫‪x <=0 ‬‬
‫וכאן יש לנו גלישה‪ .‬לכן התשובה היא לא‪.‬‬
‫– ‪– 44‬‬
‫מתי נשתמש ב ‪?Unsigned‬‬
‫לא להשתמש רק בגלל שאין צורך בשליליים!‬
‫‪‬‬
‫‪‬‬
‫קיימים מהדרי ‪ C‬שזה גורם להם ליצור קוד פחות יעיל‬
‫קל לעשות טעויות (כפי שראינו!)‬
‫אז מתי כן להשתמש ב ‪?unsigned‬‬
‫‪ ‬כשצריך טווח גדול יותר של מספרים חיוביים‬
‫‪ ‬יישומים שונים מסתמכים על ‪( modular arithmetic‬מסתמכים על הערך‬
‫אחרי הגלישה)‬
‫‪ ‬לעתים משתמשים ב ‪ Int‬כאוסף של דגלים‪.‬‬
‫‪ ‬למשל‪ ,‬קיבוץ של ‪ 6‬דגלים‪011001 :‬‬
‫‪ ‬פונקציות סטנדטיות לעתים מחזירות ‪ .unsigned‬למשל )(‪( size‬מחזיר‬
‫‪ size_t‬שזה בעצם ‪.)unsigned‬‬
‫;‪vector v‬‬
‫;)(‪unsigned s = v.size‬‬
‫– ‪– 45‬‬
?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];
– 46 –

