עבור לתוכן

עזרה במשחקים בינאריים

Featured Replies

פורסם

היי, אני נדרש לכתוב שתי פונקציות ב-C שאני לא ממש בטוח איך לממש. הראשונה צריכה לבדוק אם ניתן לחבר שני int-ים כלשהם ללא גלישה, והשניה צריכה לבדוק אם int כלשהו גדול מ-128.

הפונקציה הראשונה צריכה להחזיר 1 אם ניתן לחבר ללא גלישה, ו-0 אחרת. הפונקציה השניה צריכה להחזיר 1 אם המספר גדול מ-128, ו-0 אחרת.

אסור להשתמש בלולאות ובתנאים כלשהם, אלא רק באופרטורים כגון & | ^ ~ ! ו-shift ימינה/שמאלה. מן הסתם אסור להשתמש ב < או >...

מכיוון שמדובר ב-int, ולא ב-unsigned, בשני המקרים אני "נתקע" בבדיקה של מספרים שליליים.

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

בפונקציה השניה, הגעתי למסקנה שתיתכן גלישה רק בשני מקרים - אם שני המספרים שליליים ומסתיימים ב-10 או שניהם חיוביים ומסתיימים ב-01. מה שחשבתי לעשות הוא להזיז את שניהם 30 מקומות ימינה, כך שיישארו שני הביטים האחרונים, ואז לעשות ביניהם XOR, ככה שאם שניהם באמת מסתיימים בביטים האלו אני אקבל 0, ואם הביטים שונים אני אקבל 1, אבל הבעיה היא שזה "יתפוס" גם מספרים שמסתיימים שניהם ב-11, שאותם כמובן אין בעיה לחבר... בקיצור, אני קצת אובד עצות פה :-\

פורסם

תחזיר

last bit is not 1 && some bit after 7th bit is set

אפשר את זה בפונקציה רקורסיבית פשוטה

פורסם

קודם כל קרא קצת על Adder.

אפשר לזהות חריגה בקלות מאוד - אם שני ה-carry האחרונים שונים, אז יש לך overflow.

פורסם
  • מחבר

תחזיר

last bit is not 1 && some bit after 7th bit is set

אפשר את זה בפונקציה רקורסיבית פשוטה

אסור להשתמש ב- && ומן הסתם גם לא ברקורסיה. זה אמור להיות מימוש פשוט של 1-2 שורות.

קודם כל קרא קצת על Adder.

אפשר לזהות חריגה בקלות מאוד - אם שני ה-carry האחרונים שונים' date=' אז יש לך overflow.

[/quote']

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

א) אם הסיבית האחרונה בשני המספרים זהה, והסיבית האחרונה בסכום שונה - זו חריגה.

ב) אם שתי הסיביות האחרונות בשני המספרים הן 01 או 10, בחיבור שלהם תהיה חריגה.

את א' אני לא יודע איך לבדוק בלי להשתמש ב-if וב-&& (מה שאסור), ולבדוק את ב' אני כאמור לא ממש מצליח...

פורסם

א. לא בעיה לבדוק

tmp = a xor b
tmp1 = (a+b) xor tmp
tmp1 >> 31
return tmp1

פורסם
  • מחבר

אם הסיבית האחרונה בסכום באמת שונה מהסיביות האחרונות ב-a ו-b, ה-XOR שרשמת בשורה השניה יחזיר מספר שהסיבית האחרונה שלו היא 1, ושיפט של המספר הזה ימינה 31 מקומות ייתן לי 1-...

פורסם

אם הסיבית האחרונה בסכום באמת שונה מהסיביות האחרונות ב-a ו-b, ה-XOR שרשמת בשורה השניה יחזיר מספר שהסיבית האחרונה שלו היא 1, ושיפט של המספר הזה ימינה 31 מקומות ייתן לי 1-...

תסביר את עצמך

אם זה יתן אחד בסיבית האחרונה בtmp1 והזזנו 31 פעם ימינה, הסיבית הראשונה תשאר 1

ואז נדע על גלישה.

פורסם
  • מחבר

אני חושב שאני אצטרך לשנות את השורה האחרונה למשהו כזה:

tmp = a xor b
tmp1 = (a+b) xor tmp
tmp1 >> 31
return (tmp1 & 1)

עריכה: לא, זה גם לא יעבוד...

בוא ניקח לדוגמה שני מספרים (נקרא להם a ו-b) שהסיבית האחרונה שלהם היא 0. אם הסיבית האחרונה בסכום שלהם היא 1, יש גלישה. אחרת, אין גלישה.

ביצוע XOR על שניהם ייתן 0 בסיבית הראשונה (ונשמור את המספר שקיבלנו ב-tmp). עכשיו נבצע XOR על tmp והסכום של a ו-b.

א) אם בסכום יש 1 בסיבית האחרונה (יש גלישה), גם במספר שיתקבל מה-XOR יהיה שם אחד, ואז נזיז אותו 31 מקומות ימינה ונקבל מספר שכולו 1.

ב) אם בסכום יש 0 בסיבית האחרונה (אין גלישה), במספר שיתקבל מה-XOR יהיה שם אפס, ואז נזיז אותו 31 מקומות ימינה ונקבל מספר שכולו אפסים.

עד כאן זה בסדר, אבל שים לב מה קורה אם שני המספרים a ו-b מסתיימים ב-1, וגם הסכום שלהם מסתיים ב-1 (אין גלישה).

ה-XOR על a ו-b יחזיר 0 בסיבית האחרונה, וה-XOR השני, עם הסכום, יחזיר 1 בסיבית האחרונה, ובהזזה ימינה שוב נקבל מספר שכולו 1 - בדיוק כמו במקרה א', אלא שהפעם אין גלישה..

כמו כן, אם שני המספרים מסתיימים ב-1 והסכום שלהם מסתיים ב-0 (יש גלישה), נקבל את מה שקיבלנו במקרה ב'...

פורסם

צודק זה לא פעל כי אני מטומטם ומיהרתי

tmp = a xor b
tmp1 = (a+b) xor a or (a+b) xor b
tmp1 = tmp1 xor tmp
tmp1 >> 31
return tmp1

תבדוק לי את זה

עקבתי וזה נראה פועל

פורסם
  • מחבר

אכן עושה רושם שזה עובד ;D

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

פורסם

זה BYTE/WORD/DWORD?

פורסם
  • מחבר

כבר הסתדרתי, תודה :)

פורסם

מעניין

זו חייבת ליהיות פונקציה רקורסיבית לדעתי, או לולאה או משהו

אחרת לא עולה לי משהו אחר

פורסם
  • מחבר

דווקא לא, שים לב:

return !(!(~(x >> 31) & (x & (-1 << 7))));

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

פורסם

דווקא לא, שים לב:

return !(!(~(x >> 31) & (x & (-1 << 7))));

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

האאאאאאאא חחחחחחחחחחחחח אבל זה רמאות קצת, אבל אהבתי את היצירתיות

ה ! הראשון שלך בודק העיקר שלא יהיה אפס, שזה דיי חכם

אהבתי

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים