facebook pixel מדריך: פירוט שפת תכנות - AND (&), OR (|) ו-XOR (^) - www.4project.co.il
Main logo www.4project.co.il
כל הרכיבים לפרוייקט שלכם
עגלת קניות

העגלה ריקה

לקוחות נכבדים, אלה שעות הפעילות של המחסן במהלך פסח 2024:
ערב חג וחג ראשון (22-23/04) - המחסן סגור
חול המועד (24-25/04) - המחסן יפעל בין 8:00 עד 15:00
ערב חג וחג שני (28-29/04) - המחסן סגור
נחזור לפעילות רגילה ביום שלישי 30/04
חג שמח!

פירוט שפת תכנות - AND (&), OR (|) ו-XOR (^)


2023-06-26 10:18:40
אופרטורים לפעולות על סיביות (bitwise operators) מבצעים את החישובים ברמת הביטים (bits) של המשתנים. פעולות אלה עוזרות לפתור מגוון רחב של בעיות תכנות נפוצות. רוב התיאור בהמשך נלקח ממדריך מצויין על מתמטיקת סיביות שאפשר למצוא כאן (אנגלית).
בהמשך תמצאו תאור ותחביר של הפעולות, לפרטים נוספים קראו את המדריך המקושר.

Bitwise AND (&)

פעולת AND על סיביות מסומנת בשפת C/C++ בעזרת סימן & אחד והוא משמש לביצוע פעולת AND על ביטויים עם מספרים שלמים (integer expressions). פעולת AND על סיביות פועל על כל סיבית בנפרד, בהתאם לערכי הסיביות באותו המיקום בשני הביטויים. הכלל לביצוע הפעולה הוא: אם שתי הסיביות הן בערך 1, אז סיבית התוצאה תהיה גם 1, בכל מקרה אחר התוצאה תהיה 0. דרך נוספת להציג את הכלל:
קוד: בחר הכל
0  0  1  1    operand1
0  1  0  1    operand2
----------
0  0  0  1    (operand1 & operand2) - returned result


ב-Arduino אורך המשתנה מסוג int הוא 16 סיביות, כך שבכל פעולת & בין שני ביטויים מסוג int מתבצעות 16 פעולות AND בו זמנית.

קוד: בחר הכל
int a =  92;    // in binary: 0000000001011100
int b = 101;    // in binary: 0000000001100101
int c = a & b;  // result:    0000000001000100, or 68 in decimal.

בדוגמה זו כל 16 סיביות של משתנים a ו-b מטופלות ע"י פעולת AND על הסיביות והתוצאה של 16 סיביות נשמרת במשתנה c, המספקת מספר בינרי בערך 01000100 שזהו מספר 68 בייצוג דצימלי.
אחד השימושים הנפוצים בפעולת AND על הסיביות זה בחירת סיבית (או סיביות) ממשתנה מסיג int. לפעולה זו בדרך כלל קוראים מיסוך (masking). ראו דוגמה בהמשך העמוד.

Bitwise OR (|)

פעולת OR על סיביות מסומנת בשפת C/C++ בעזרת סימן | אחד. בדומה לאופרטור &, הפעולה מתבצעת על כל סיבית בנפרד בין שני הביטויים הרשומים משני צידי הסימן |, אבל הפעולה מתבצעת לפי הכלל: אם ערך של לפחות אחת מהסיביות הוא 1, אז התוצאה תהיה 1, אחרת התוצאה היא 0. במילים אחרות:
קוד: בחר הכל
0  0  1  1    operand1
0  1  0  1    operand2
----------
0  1  1  1    (operand1 | operand2) - returned result

להלן דוגמה של פעולת OR על סיביות בקוד C/C++:
קוד: בחר הכל
int a =  92;    // in binary: 0000000001011100
int b = 101;    // in binary: 0000000001100101
int c = a | b;  // result:    0000000001111101, or 125 in decimal.


תוכנית לדוגמה

פעולה נפוצה עבור אופרטורים AND ו-OR על סיביות היא מה שמתכנתים מכנים Read-Modify-Write (תקרא, תשנה, תשמור). במיקרובקר, פורט (port) זה 8 סיביות המציינות את מצב הקווים. כתיבה לפורט שולטת על כל ה-8 קווים יחד.
PORTD הוא קבוע מובנה המציין את מצב הקווים הדיגיטליים 0, 1, 2, 3, 4, 5, 6, 7. אם יש 1 בסיבית המציינת את מצב הקו, הקו שיצא מהבקר יהיה ב-HIGH. (הקווים צריכים להיות מוגדרים כקווי יציאה בעזרת פקודת ה-()pinMode.) אז אם כותבים PORTD = B00110001, אנחנו נגרום לקווים 2, 3 ו-7 להיות במצב HIGH. בעיה בכתיבה היא שבצורה זו שאנחנו יכולים לשנות גם את הערכי הקווים 0 ו-1 שהם קווי תקשורת טורית של Arduino, כך שזה עלול לפגוע בתקשורת.

האלגוריתם לתוכנית יהיה:
לקבל ערך של PORTD ולאפס רק את הסיביות של הקווים שאנחנו רוצים לשלוט בהם (בעזרת פעולת AND על סיביות).
לאחד את ערך ה-PORTD שקיבלנו עם ערכים החדשים של הקווים שאנחנו רוצים לשלוט בהם (בעזרת פעולת AND על סיביות).
קוד: בחר הכל
int i;     // counter variable
int j;

void setup() {
    DDRD = DDRD | B11111100; // set direction bits for pins 2 to 7, leave 0 and 1 untouched (xx | 00 == xx)
    // same as pinMode(pin, OUTPUT) for pins 2 to 7
    Serial.begin(9600);
}

void loop() {
    for (i=0; i<64; i++){
        PORTD = PORTD & B00000011;  // clear out bits 2 - 7, leave pins 0 and 1 untouched (xx & 11 == xx)
        j = (i << 2);               // shift variable up to pins 2 - 7 - to avoid pins 0 and 1
        PORTD = PORTD | j;          // combine the port information with the new information for LED pins
        Serial.println(PORTD, BIN); // debug to show masking
        delay(100);
    }
}


Bitwise XOR (^)

בשפת C/C++ יש פעולה כצת יוצאת דופן הנקראת Exclusive OR הידועה גם כפעולת XOR על סיביות. הסימון של הפעולה הוא ^. הפעולתו דומה לפעולת OR על סיביות, רק שהוא נותן תוצאה של 0 גם כאשר שתי הסיביות הן 1:
קוד: בחר הכל
0  0  1  1    operand1
0  1  0  1    operand2
----------
0  1  1  0    (operand1 ^ operand2) - returned result

דרך אחרת להסתכל על פעולת XOR על סיביות היא שתוצאה של 1 מתקבלת כאשר שתי הסיביות שונות ותוצאה של 0 כאשר שתי הסיביות זהות.
להלן דוגמה קלה של קוד:
קוד: בחר הכל
int x = 12;     // binary: 1100
int y = 10;     // binary: 1010
int z = x ^ y;  // binary: 0110, or decimal 6

לעתים קרובות משתמשים באופרטור ^ כדי להחליף (toggle) ערכים של סיביות מסוימות בביטוי של מספר קבוע (integer expression), כלומר להחליף את הערך שלהן מ-0 ל-1 או מ-1 ל-0. בפעולת XOR, אם יש סיבית בערך 1 במסכה (mask), ערך של אותו הביט בביטוי יתהפך. אם יש סיבית בערך 0 במסכה, אז ערך הסיבית בביטוי תשמר.
להלן תוכנית שתהבהב בקו דיגיטלי מספר 5:
קוד: בחר הכל
// Blink_Pin_5
// demo for Exclusive OR
void setup() {
    DDRD = DDRD | B00100000; // set digital pin five as OUTPUT
    Serial.begin(9600);
}

void loop() {
    PORTD = PORTD ^ B00100000;  // invert bit 5 (digital pin 5), leave others untouched
    delay(100);
}


ראו גם:

&& (Logical AND)
|| (Logical OR)

פירוט שפת תכנות לסביבת Arduino


עמוד זה הוא תרגום של Bitwise AND (&), Bitwise OR (|), Bitwise XOR (^) לפי רישיון Creative Commons Attribution-ShareAlike 3.0.