Logo

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

ראשי > תיכנות > זיכרון המחשב

07/07/2007 16:06:31 T4uSBaZ
כל שאר הפורומים מתים =\ אתם יודעים.

איך מייצגים מספר float או double בזיכרון המחשב?
הרי הכל בינארי.
07/07/2007 18:32:10 HLL
וווווווואאאאאהה
עכשיו הלכת רחוק
יש מאחורי זה תורה שלמה
הרבה הרבה בהצלחה
והרבה הרבה מזל טוב
http://steve.hollasch.net/cgindex/coding/ieeefloat.html
08/07/2007 06:46:52 T4uSBaZ
ייאי תודה : )

HLL מלך ה low_level אני סוגד לך !! : )

ד.א. בעברית:
http://www.google.co.il/url?sa=t&ct=res&cd=5&url=http%3A%2F%2Fwww.cs.biu.ac.il%2F~muskat%2FFloat66.doc&ei=yGKQRv7CG6GcnQPf8LnpCg&usg=AFQjCNEzp0t9RG170Mh9-crKCnYhGMe9mQ&sig2=H4SDH37tT6JQrrOEE-SRHA

עוד שאלה עלתה לי , משהו שלא הבנתי מקודם אבל שכחתי לשאול..

הרי משתנה signed char יכול להכיל -128 עד +127 בזיכרון המחשב.
לעומת זאת משתנה unsigned char יכול להכיל 0 עד 255 בזיכרון המחשב.

גודלו של char הוא בית אחד (8 סיביות), והסיבית השמאלית ביותר מציינת האם המספר שלילי הוא חיובי, כך שנשארו 7 סיביות לייצוג המספר , ומכאן 2 בחזקת 7 - יש לנו 128 אפשרויות למספרים שליליים או חיוביים.
אז כיצד אנחנו מייצגים unsigned char בזיכרון?
לדוגמא, אני רוצא לייצג 255 בזיכרון, בבינארית המספר יצא 11111111. הסיבית השמאלית ביותר היא 1, לכן המחשב אמור לראות את המספר כמספר שלילי , -128.
כיצד הוא רוצה אותו כ255 ?

[ההודעה נערכה על-ידי T4uSBaZ ב-08/07/2007 07:12:43]
08/07/2007 09:56:39 Ratinho
כנראה שבunsigned הוא שומר אותו בצורה של 8 ביטים מלאות, בלי סימן, או אולי, אם יש מספר שלילי, הוא מחסר אותו מ 128
08/07/2007 17:17:51 devil kide
ציטוט:ייאי תודה : )

HLL מלך ה low_level אני סוגד לך !! : )

ד.א. בעברית:
http://www.google.co.il/url?sa=t&ct=res&cd=5&url=http%3A%2F%2Fwww.cs.biu.ac.il%2F~muskat%2FFloat66.doc&ei=yGKQRv7CG6GcnQPf8LnpCg&usg=AFQjCNEzp0t9RG170Mh9-crKCnYhGMe9mQ&sig2=H4SDH37tT6JQrrOEE-SRHA

עוד שאלה עלתה לי , משהו שלא הבנתי מקודם אבל שכחתי לשאול..

הרי משתנה signed char יכול להכיל -128 עד +127 בזיכרון המחשב.
לעומת זאת משתנה unsigned char יכול להכיל 0 עד 255 בזיכרון המחשב.

גודלו של char הוא בית אחד (8 סיביות), והסיבית השמאלית ביותר מציינת האם המספר שלילי הוא חיובי, כך שנשארו 7 סיביות לייצוג המספר , ומכאן 2 בחזקת 7 - יש לנו 128 אפשרויות למספרים שליליים או חיוביים.
אז כיצד אנחנו מייצגים unsigned char בזיכרון?
לדוגמא, אני רוצא לייצג 255 בזיכרון, בבינארית המספר יצא 11111111. הסיבית השמאלית ביותר היא 1, לכן המחשב אמור לראות את המספר כמספר שלילי , -128.
כיצד הוא רוצה אותו כ255 ?



[ההודעה נערכה על-ידי T4uSBaZ ב-08/07/2007 07:12:43]
כמו שאמרת, הוא שומר אותו כבלתי מסומן.
08/07/2007 23:38:59 T4uSBaZ
אז איך אפשר לדעת עם הוא signed או unsigned?
איך המחשב יודע?

הרי 11111111 יכול להיות 255 , ויכול להיות -128.

איך הוא יודע.?
09/07/2007 21:06:13 HLL
וויאיי
אמרתי כבר שאני אוהב שאלות כיפיות? - כיף כיף כיף!
אוקי
המורה שלי בזמנו הסבירה את זה מאוד מאוד טוב - המשתנה הוא אותו משתנה - זה תלוי איזה ’משקפיים’ אתה שם על הקוד שיסתכל כראוי עליו ....

... הרחבה ...

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

כשאתה מבצע איזושהיא פעולת השוואה (או הזזה(SHL\SHR), כפל * או חילוק /)
רק אז הקומפיילר מתייחס למספר מסומן ולא מסומן באופן שונה,
הכיצד:

- כשאתה מבצע shr לדוגמא (אופרטור << בשפת סי) מה שוקרה בעצם שסיבית הסימן נמרחת בצד שמאל, בתאכלס, האופרטור << על מספר מסומן א-י-נ-ו מתקמפל ל shr אלא ל sar (קח את זה בערבון מוגבל אני לא ממש זוכר! מפה והלאה)
Shift Aritmatic Right זה אומר שזה מזיז את המספר ימינה ומורח את סיבית הסימן...
כאשר אתה עושה >> על מספר לא מסומן זה מתקמפל ל sal (המקבילה המסומנת של shl).

- השוואה, בהשוואה כשאתה בודק האם משתנה לא מסומן גדול ממשתנה שני לא מסומן (שוב מדברים בשפת סי , אופרטורים < ן >), הדבר מתורגם להוראות ja ו jb
(above, below)
כאשר אתה מבצע את הפעולה על מספרים מסומנים, זה מתקמפל ל jg ו (סעמק שכחתי!) חח אבל זה דומה

- כפל / חילוק - יש לך DIV ו MUL , למספרים בלתי מסומנים, ו IMUL ו IDIV למסומנים


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

יום מצויין גם לך :)
[ההודעה נערכה על-ידי HLL ב-09/07/2007 21:11:27]
09/07/2007 23:12:22 devil kide
Bוסיף קצת על מה שהלל אמר-רק בדוגמא , לא בהסבר, ההסבר היה מעולה.


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

איך קורה מצב שבו אנחנו נשמור את המספר 65 והמחשב ידע להתייחס אליו כאל מספר ולא כאל תו(A)?
כמו שהלל אמר, "זה תלוי איזה ’משקפיים’ אתה שם על הקוד שיסתכל כראוי עליו".
09/07/2007 23:25:23 HLL
אממ לאדע כמה ברור היה דויל קיד
אני אדגים את מה שהוא אמר
קוד:unsigned char a=’a’;
signed char b=’b’;

printf("%c%c",a,b);
מדפיס a ו b כרגיל ...
09/07/2007 23:58:55 T4uSBaZ
וואי תודה עכשיו הבנתי.
וחוץ מזה אני חושב שגם ההוראה ש"מדפיסה" על המסך את המספר או התו, גם כן שונה בכל סוג משתנה.
כי בsigned היא מתייחסת (לדוגמא ב char) ל7 הסיביות האחרונות, ולראשונה כסימן פלוס מינוס. ובunsigned זה פקודה שונה לגמרי, כי היא מתייחסת לכל 8 הסיביות.

10x folks : )
10/07/2007 00:41:44 devil kide
ציטוט:אממ לאדע כמה ברור היה דויל קיד
אני אדגים את מה שהוא אמר
קוד:unsigned char a=’a’;
signed char b=’b’;

printf("%c%c",a,b);
מדפיס a ו b כרגיל ...
לא הבנת.
המספר 65 מיוצג בזכרון 01000001
והתו A גם מיוצג כ 01000001
כי היצוג של A בASCII זה 65.
10/07/2007 21:13:42 T4uSBaZ
דרך אגב, עוד כמה שאלות..
מצטער ממש עם אני מציף!

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

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

אינני מעוניין בבסיסים עשרוניים מכיוון שאני מנסה מעיין ליצור את כל הגלגל מחדש... זה מה שאני אוהב ב low-level :)

3. איך אפשר לדעת מהו סוג משתנה ? חשבתי על גודלם, אבל sizeof(int)==sizeof(long) , וחוץ מזה sizeof(signed int)==sizeof(unsignedint) ..

הבנתי שהמהדר מטפל בזה..
האם זה אומר שאני לא יכול לבצע את הדברים האלו תחת C?
10/07/2007 23:13:37 devil kide
אני לא חושב שניתן להגדיר רק סיבית בודדת אחת, מכיוון שאם תשתמש בסיבית אחת בכל מקרה כל התא יהיה "תפוס".אולי משתנה בוליאן משתמש בסיבית אחת.

אפשר "להזיז" את תוכן התא ולקבל את התוצאה בדגל O אם אני לא טועה. יש לי חבר שכתב איזה שהוא קוד שעושה כאלה דברים, ממש מערכת לניהול מידע בצורה כזאת.
דבר איתי בICQ, אני יבדוק אם הקוד הזה נמצא אצלי איפה שהוא על המחשב.

3. לא הבנתי....
10/07/2007 23:31:04 T4uSBaZ
הממ תודה רבה.. ישנם עוד אפשרויות?
ולגבי 3.. בוא נעשה דבר יותר פשוט.
אני צריך פונקציה שמקבלת כל סוג של משתנה ..
ומחזירה את הסוג שלו (כולל signed או unsigned).

או שאולי אפשר איזה קוד, שיעשה משהו כזה:
קוד:
switch(vartype)
{
case CHARVAR: charf();
break;
case INTVAR: intf();
break;
case UNSIGNEDCHARVAR: char(f);
break;
default: something();
break;
}

הבעיה לגלות את vartype. (סוג המשתנה)[ההודעה נערכה על-ידי T4uSBaZ ב-10/07/2007 23:31:41]
11/07/2007 20:41:01 HLL
ציטוט:דרך אגב, עוד כמה שאלות..
מצטער ממש עם אני מציף!

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

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

אינני מעוניין בבסיסים עשרוניים מכיוון שאני מנסה מעיין ליצור את כל הגלגל מחדש... זה מה שאני אוהב ב low-level :)

3. איך אפשר לדעת מהו סוג משתנה ? חשבתי על גודלם, אבל sizeof(int)==sizeof(long) , וחוץ מזה sizeof(signed int)==sizeof(unsignedint) ..

הבנתי שהמהדר מטפל בזה..
האם זה אומר שאני לא יכול לבצע את הדברים האלו תחת C?

1. - תכיר, Bitwise operators
http://www.phim.unibe.ch/comp_doc/c_manual/C/CONCEPT/bitwise.html

2. אני מאמין שאני יכול להגיד כנ"ל

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

את 3 , אתה לא רק לא יכול לבצע בסי, אתה לא יכול לבצע גם בכל שפה אחרת ללא שינוי הקונספט שלך שמדבר על ’טיפוס משתנה’ (לקונספט בסגנון JAVA\.net)
[ההודעה נערכה על-ידי HLL ב-11/07/2007 20:46:39]
11/07/2007 21:09:22 T4uSBaZ
תודה רבה : )

רק שאלה אחת קטנה לראות שהבנתי נכון: לדוגמא יש פונקציה printf שמקבלת מחרוזת %d ומספר כלשהו char.

אז בעצם יש שתי פקודות לint , אחד ל signed ואחד ל unsigned.
והמהדר בעצם מחליט במי להשתמש תוך כדי קימפול, כן?[ההודעה נערכה על-ידי T4uSBaZ ב-11/07/2007 21:11:48]
12/07/2007 20:16:47 HLL
עה? לא...
יש לזכור שפונקצית printf היא פונקציית ספרייה והיא מקומפלת מראש...
איך היא יודעת בתור איזה טיפוס להתייחס למשתנה, לפי מחרוזת הפורמט שלך - שמבקרה שלך "%d" אומרת signed int.
13/07/2007 14:51:57 bla27
ב C++ יש מנגנון RTTI ( Run Time Type Information?) שמאפשר לך לבדוק את טיפוס המשתנה בזמן ריצה לא?
14/07/2007 15:57:11 HLL
כן יש משהוא כזה, זה דורש כמובן להוסיף Overhead ב Executable (ונראה לי שזה גם עוזר ב Reverse-engineering).
תאמת לעולם לא היה לי צורך בזה, ולא ניסיתי את זה ... יש דרכים אחרות לעשות דברים בסגנון הזה ב CPP
19/07/2007 01:27:58 bla27
נו בטח.. אם צריכים להשתמש בזה בדרך כלל זה תוצאה של עיצוב תוכנה לקוי..
עמודים: 1