Logo

רד-בורד: ארכיון

ראשי > תיכנות > bitwise operations

21/11/2007 16:25:52 T4uSBaZ
לאחרונה שוב התחלתי לחקור את כל הנושא הזה.
התחלתי לחקור בעצמי מכיוון שבשום מקום אני לא מוצא תשובות,
אני מקווה שאוכל לקבל פה תשובה .. (או לפחות השערה).

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

ובכל זאת, נניח ויש לי תוכנית שהגדרתי בה:
קוד:
char i=-128; //binary:10000000
printf("%d",i<<1); //suppous to be 00000000 = 0

output: -256


הoutput יוצא 256 שזה לא הגיוני כי זה צריך להיות 0.
לפי מה שאמור להיות הביט ראשון, (1) אמור להעלם.. כי זה הזזה של >>. האם יכול להיות שהוא מחליף את הביטים של המשתנים לפניו?
אחרת מה קורה עם printf שמראה תוצאות כאלו?
בקיצור כל מני דברים כאלו קורים. וכנ"ל ב unsigned.
משום מה זה מתקשה להבין מהו המספר? או שלא יודע מה.

ולדוגמא, כשאני מחלק מספר ב2.. במקרה של signed.
אם אני מחלק מספר שלילי, לדוגמא -128 (10000000) ב2 על ידי סיביות כך:
קוד:
int i=-128;
i>>1;


יתווסף לי 1 משמאל (11000000) ואכן התוצאה -64.
אך איך המחשב יודע לגבי זה? אם הקומפיילר כשמעביר את זה לשפת מכונה, נותן פקודה של ASR (שקיימת לרוב בשפת מכונה, פירושה Arithmetical shift right) אז למה התוצאה לא יוצאת (01000000) ?

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

אולי אסמבלי יענה לי עלזה יותר טוב?
אנא , הגיבו ..

אגב, אני מודע לביט הבקרה .. (1=שלילי, 0=חיובי) וכו’ .


אנשים, אני מת ללמוד low level. פשוט מת. מקורות!!
23/11/2007 02:06:28 HLL
טוב - פשוט תשלח לי הודעה פרטית פעם הבאה וזהו - הרי אתה כבר יודע מי יענה לך ...
סתם אני לא מעודד את זה כי פה כולם יכולים לראות

1. לגבי אופרטור >> , מה שקורה זה שלקומפיילר יש טיפוס דיפולטי שאליו הוא מייחס את התוצאה, במקרה הזה אני מניח שזה int.
כלומר בעצם מה שקורה זה שהזזת בייט בודד שמאלה, אבל האופרטור החזיר לך int. ה int נחשב ב %d כרגיל, ואתה רואה בידיוק מה שצריך, את המספר עם הביט מוזזת שמאלה. - אם היית לדוגמא עושה משו כזה
קוד:
char i=-128; //binary:10000000
i<<=1;
printf("%d",i);
היית מקבל 0.
2. לגבי Arithmatic shift, שים לב Arithmatic shift מחשיב את סיבית הסימן, מה שהוא עושה, זה מורח את סיבית הסימן במקום להכניס אפסים, אם היה לך -64 לדוגמא = 11000000 ותזיז ימינה תקבל -32 = 11100000.
אותו דבר אמור לקרות כשאתה רוצה להגדיל טיפוס מסומן (מוסיף ערכים מצד שמאל במקום להזיז), מה שאתה עושה זה מורח את סיבית הסימן עד לגודל הרצוי.
למה? שים לב ש -128 לדוגמא יכול להיות:
א. 10000000
ב. 1111111110000000
ג. 11111111111111111111111110000000
וכו’, הבנת את הרעיון

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

שבת שלום, והרבה בהצלחה - ואל תהסס לכתוב פה שוב,
(תה יודע בגלל שהפורום מפוצץ בהודעות וכאלה אני לא רוצה שתהייה הצפה )
[ההודעה נערכה על-ידי HLL ב-23/11/2007 02:31:57]
23/11/2007 08:49:47 T4uSBaZ
חחח כן.. מממש מפוצץ =]

ותאמת שאני מתחיל ללמוד אסמבלי ( בבית ספר, עם כתות יא’ יב’ :] )

תודה רבה![ההודעה נערכה על-ידי T4uSBaZ ב-23/11/2007 08:49:59]
עמודים: 1