visual vs unix

white shadow 3

New member
visual vs unix

בוקר טוב. מקווה שנצליח להגיע לפתרון


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

כשאני מקמפל את הקוד ב-UNIX דרך:
gcc -g -O test.c -o test.exe
test.exe/.
אני מקבל את אותם פלטים שקיבלתי ב-visual חוץ מבשורה אחת
(עבור הפלט 10 המיוצג ב-64 סיביות תחת האילוץ של "להסיר אפסים מובילים" הפלט שהתקבל ב-visual היה A כפי שרציתי, והפלט שהתקבל ב-unix היה 000000000000000)

האם יש איזשהיא דרך לבדוק/לדעת איפה היה השינוי בין 2 ההרצות ולמה בהרצה ב-unix מתקבל לי פתרון שונה?

תודה מראש ושבוע טוב,
 

פרסאוס

New member
תן לי לחבוש את כובע הקסמים שלי ולראות את הקוד שלך...

לא, לא עובד.
כנראה שתצטרך להעלות אותו.
 

white shadow 3

New member
הי,

שלחתי לך בהודעה פרטית (מסיבה אישית כלשהיא), מקווה שזה בסדר מבחינתך
&nbsp
תודה בכל מקרה!
 

פרסאוס

New member
הודעות בענייני קוד יש להעלות לכאן ע"מ

שאנשים נוספים יוכלו ללמוד מהן. זוהי מטרתו של (ה)פורום.
 

white shadow 3

New member
מצורף קובץ עם קטע הקוד

הסיפור הוא כזה: הפונקציה מקבלת ערך value מסוים בפורמט 64 ביטים,
מקבלת מספר ביטים שרלוונטים לנו במספר הזה (לדוגמא אם מספר הביטים הוא 4 אז מעניינים אותנו רק ארבעת הביטים הראשונים במספר), ומקבלת 1 או 0 בהתאם לסוג ה-value שהיא קיבלה (אם הערך הוא 1 אז היא קיבלה ערך שצריך להמיר ל-hexa ללא אפסים בזנב, אם קיבלה 0 אז צריכים להמיר ל-hexa ללא אפסים מובילים.

*הערה: במקרה הראשון שבו is_frac=1 ה-value שנשלח לפונקציה הוא מסוג unsined int ב-64 סיביות, במקרה השני הפונקציה מקבלת value שהוא מסוג int ב-64 סיביות כך שהערך עצמו של המספר עלול להשתנות, אך הייצוג הבינארי שלו לא משתנה והפונקציה עובדת על הייצוג הבינארי.

עכשיו, בקריאה הראשונה הפונקציה (כאשר אני שולח לה value מסוג unsigned int 64, שולח לה מספר ביטים ושולח לה is_frac=1 הכל בסדר...

הבעיה משום מה מתחילה איפשהוא בקריאה השניה, כאשר אני שולח לה ערך מסוג int 64, שולח לה מספר ביטים - שהוא תמיד קבוע במקרה הנ"ל - ומיוצג בקריאה לפונקציה ע"י:
zz (unsigned char)(8*sizeof(uint64)) zz
ושולח לה is_frac=0.
ניסיתי לבדוק איפה במהלך הפונקציה מתחילות הבעיות אז הדפסתי בשורה הראשונה של הפונקציה את ערכי value, num_bits ו-is_frac וקיבלתי על המסך את הערכים שציפיתי לקבל (קיבלתי במספר הביטים הרלוונטי הוא 64, קיבלתי שאם המספר value שהיה int 64 היה חיובי אז קיבלתי אותו ממש, אם הוא היה שלילי אז קיבלתי מספר אחר אבל עם אותו ייצוג בינארי כמו המספר השלילי...לדוגמא אם הערך המקורי היה 2- בייצוג של
1111111111111111111111111111111111111111111111111111111111111110
אז קיבלתי על המסך את המספר:
18446744073709551614 )

הבעיה צצה כאשר הדפסתי את הערך של b במהלך ריצת ה-while.
כאן, לא משנה איזה ערכי קלט מקוריים הכנסתי, כל הזמן אני מקבל ש-b כבר בפעם הראשונה ש-while רץ מקבל את הערך 0 ואני ממש שובר את הראש מה קורה כאן כי עד לשורה זו לא היה שום שינוי מהריצה בפעם הראשונה של הפונקציה שם הכל עבד בסדר... (ההבדל היחידי שיכולתי לחשוב עליו זה שבפעם הראשונה שקראתי לפונקציה אז בפרמטר של unsigned char num_bits שלחתי תוצאה מפונקציה אחרת, וכאן שלחתי
zz (unsigned char)(8*sizeof(uint64)) zz
אבל אני לא יודע אם זאת באמת בעיה כי כאשר הדפסתי את הערכים שהתקבלו בפונקציה - היה מודפס שם 64 ....

אשמח לתשובה,
תודה מראש!
 

white shadow 3

New member
אני חושב שהצלחתי להבין איפה הבעיה...

הבעיה מתחילה עוד קודם - בשורה שכתוב בה:
zz mask_a=(1ll<<num_bits)-1; zz
הערך של הביטוי הזה יוצא 0 למרות שאני שיערתי שאם אני מזיז את הספרה 1 64 צעדים ימינה אז הערך שיתקבל שם יהיה 0 (כי ה-1 יצא מגבולות 64 הביטים) ואז אם אחסר מזה 1 אני אקבל וקטור של 64 ביטים שכולו 1-ים...
למה זה לא מה שקורה?
(יכול להיות שזה קשור בצורה כלשהיא ל- num_bits שלי, שכנראה נשלח לפונקציה בצורה לא תקינה...? (למרות שכאשר אני מדפיס את הערך של המשתנה הזה אני מקבל על המסך 64..)

ת ודה
 

white shadow 3

New member
אגב, האם הבעיה טמונה בכך שהזזת הוקטור 64 ימינה מביאה לחריגה

מחוץ לתחום ==> "התנהגות בלתי צפויה"?
א. למה זה גורר התנהגות בלתי צפויה ולא משאיר לי את הוקטור של 64 הביטים פשוט עם אפסים?
ב. במקרה הנדון - האם יש לי דרך אלגנטית לעקוף את זה? (בינתיים עשיתי שם תנאי שאם מספר הביטים גדול מ-63 אז mask_a פשוט מקבל את (0~), אחרת מבצע את השורה שהייתה כתובה שם גם ממקודם ונראה שזה פתר לי את הבעיה שהייתה כי כרגע (לפחות לכמה קלטים הספציפיים שבדקתי) ניכר כי הפלטים עומדים בציפיות...
 

BravoMan

Active member
איך מוגדר אצלך uint64?

זה לא טיפוס סטנדרטי של C, מנין הוא בא?
 

BravoMan

Active member
אני לא יודע מה עושה הסטודיו ב-64 סיביות

אבל gcc במערכות לינוקס משאיר int, כולל unsigned בגודל 32 ביט.
&nbsp
אני מציע שתשמש בטיפוסים הסטנדרטיים של c99 (ספציפית uint64_t), או תשמש ב-typedef ל-unsigned long.
 

BravoMan

Active member
טוב, ניסיתי להבין את תיאור הבעיה שלך ומה הפונקציה

עושה, אבל לא ממש הצלחתי.
&nbsp
בוא נעשה כזה דבר:
1. תרשום ליד שם כל פרמטר בדיוק מה הוא אמור לעשות.
2. תיתן דוגמה לקלט לפונקציה, לפלט שקיבלת, ולפלט שציפית לקבל.
 
למעלה