JavaRush /בלוג Java /Random-HE /אופרטורים לוגיים ב-Java

אופרטורים לוגיים ב-Java

פורסם בקבוצה
פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 1

פעולות לוגיות ב-Java

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

(a | b) | (c < 100) & !(true) ^ (q == 5)
הוא ביטוי לוגי מורכב עם ארבעה אופרנדים: (a | b), where аand bהם משתני טיפוס boolean (c < 100) (true) (q == 5) , בתורו, ביטוי לוגי פשוט (a | b)מורכב גם משני ארגומנטים של אופרנדים. אופרנד לוגי הוא ביטוי שניתן לומר שהוא נכון או שקר, נכון או שקר . בשפה ג'אווה, אופרנד בוליאני הוא ביטוי של סוג booleanאו בוליאני, למשל:
  • (2 < 1)- אופרנד לוגי, ערכו שקרי
  • true- אופרנד לוגי שערכו נכון ללא ספק
  • boolean a- יכול להיות גם אופרנד לוגי, כמו Boolean a
  • int a = 2- אינו אופרנד לוגי , הוא רק משתנה מסוגint
  • String a = "true"הוא גם לא אופרנד לוגי . זוהי מחרוזת שערך הטקסט שלה הוא "true".
הפעולות הלוגיות הבאות זמינות ב-Java:
  • שלילה לוגית , המכונה גם NOTהיפוך. ב-Java, זה מסומן על ידי !הסמל " " לפני האופרנד. חל על אופרנד אחד.
  • הגיוני ו , זה גם ANDצירוף. מסומן בסמל " &" בין שני האופרנדים שעליהם הוא מוחל.
  • לוגי או בג'אווה , זה גם - OR, זה גם ניתוק. ב-Java, זה מסומן על ידי הסמל " |" בין שני אופרנדים.
  • ביטול בלעדי או , XOR, קפדני. ב-Java, זה מסומן על ידי הסמל " ^" בין שני אופרנדים.
  • ב-Java, אופרטורים לוגיים כוללים את המותנה או , המסומן כ- ||, כמו גם את המותנה ו- &&.
הערה: גם בלוגיקה מתמטית הם רואים את יחס השקילות, במילים אחרות, שוויון. עם זאת, ב-Java, אופרטור השוויון==אינו נחשב לאופרטור לוגי. תשומת הלב! ב-Java, האופרטורים הלוגיים&,|וכן^חלים על מספרים שלמים. במקרה זה, הם פועלים בצורה מעט שונה ונקראים אופרטורים לוגיים סיביים (או סיביים). עליהם - לקראת סוף המאמר. הבה נתבונן בטבלה עם תיאור קצר של כל אחד מהאופרטורים הלוגיים של Java, ולהלן נתאר אותם ביתר פירוט ונספק דוגמאות קוד.
מפעיל Java שֵׁם סוּג תיאור קצר דוגמא
! "לא" הגיוני (שלילה) Unary !xפירושו "לא x". מחזירה true אם האופרנד הוא שקר . מחזירה false אם האופרנד נכון . boolean x = true;
לאחר מכן
// !x == false
& AND לוגי ( AND, כפל) בינארי מחזירה true אם שני האופרנדים נכונים . a = true;
b = false;
לאחר מכן
a & b == false
| OR לוגי ( OR, תוספת) בינארי מחזירה true אם לפחות אחד מהאופרנדים נכון . a = true;
b = false;
לאחר מכן
a | b == true
^ בלעדי לוגי OR ( XOR) בינארי מחזירה true אם אחד ויחיד מהאופרנדים הוא אמת . מחזירה false אם שני האופרנדים אמיתיים או שקריים . בעיקרו של דבר, זה מחזיר נכון אם האופרנדים שונים. a = true;
b = false;
לאחר מכן
a ^ b == true
&& AND מותנה (קצר AND לוגי) בינארי זהה ל-, &אבל אם האופרנד משמאל &ל- False , האופרטור הזה מחזיר false מבלי לבדוק את האופרנד השני.
|| OR מותנה (OR לוגי קצר) בינארי זהה ל-, |אבל אם האופרטור משמאל הוא true , האופרטור מחזיר true מבלי לבדוק את האופרנד השני.

פעולות לוגיות בקורס JavaRush

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

פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 2

מפעיל שלילה לוגית!

אופרטור זה הוא אונרי, כלומר הוא חל על ביטוי או אופרנד בוליאני בודד. זה מאוד פשוט להבנה, כמו כל שלילה: האופרטור פשוט משנה את משמעות הביטוי להיפך. טבלת אמת או תוצאות של ביצוע פעולת שלילה:
הערך של א
שֶׁקֶר נָכוֹן
נָכוֹן שֶׁקֶר
דוגמא. פעולת שלילה לוגית
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       System.out.println(!a); // here our boolean expression reverses its value
       System.out.println(!false); // non-false expression, as you might guess, will be equal to... what?
       System.out.println(!(2 < 5)); // expression (2 < 5) is true, so its negation is false

   }
}
הפלט של התוכנית יהיה כדלקמן:

false
true
false

לוגי AND - &, כמו גם AND - && מותנה

AND או צירוף לוגי מוחל על שני ביטויים, והתוצאה שלו תהיה נכונה רק אם שני האופרנדים נכונים. כלומר, אם אחד מהאופרנדים aאו bהוא false , אז הביטוי a & bיהיה false ללא קשר לערך של האופרטור השני. אם אתה מדמיין ש- true הוא המספר 1 ושקר הוא 0, אז האופרטור &עובד בדיוק כמו כפל רגיל. לכן, AND לוגי נקרא לעתים קרובות "כפל לוגי". ודרך אגב, עובדה זו עוזרת לזכור במהירות את פעולת המפעיל &ולא לבלבל בינה לבין הלוגיקה או המפעיל |. טבלת האמת וזו גם תוצאה של עבודת המפעיל&
א ב a&b
נָכוֹן נָכוֹן נָכוֹן
נָכוֹן שֶׁקֶר שֶׁקֶר
שֶׁקֶר נָכוֹן שֶׁקֶר
שֶׁקֶר שֶׁקֶר שֶׁקֶר
AND, זה גם צירוף, דוגמאות:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(a & b); // if we multiply true by false, we will definitely get false
       System.out.println(a & c); // true to true will be true
       System.out.println(false & (2 > 5));
 System.out.println((2 < 5) & false);
 // regardless of the truthfulness of the expression in brackets, in which case we have to be content with false
   }
}
תוצאת התוכנית:

false
true
false
false
האופרטור &&נקרא לפעמים "קצר AND". זה מייצר את אותה תוצאה כשעובדים עם אופרנדים לוגיים כמו האופרטור &. עם זאת, יש הבדל בעבודתו עצמה. אז, כבר שמתם לב שאם a & bהאופרנד בביטוי ( ) aהוא false , אז זה לא הגיוני לבדוק את הערך של האופרנד b: התוצאה של הפעולה תהיה בהחלט false . אז אם אנחנו לא צריכים ביסודו את הערך של האופרנד השני, באמצעותו &&אנחנו מצמצמים את מספר החישובים בתוכנית. אם נחליף את כל האופרטורים בדוגמה &ב- &&, התוצאה תהיה זהה לחלוטין, אבל התוכנה עצמה תרוץ קצת יותר מהר (אם כי לא נשים לב לכך, היות ומדובר במילי-מיקרו... בקיצור , יחידות זמן קטנות מאוד).

OR לוגי הוא האופרטור |, כמו גם OR מותנה הוא האופרטור ||

האופרטור OR ב-Java מיוצג על ידי הסמל |. OR לוגי או ניתוק מוחל על שני ביטויים, והתוצאה שלו תהיה שקר אם ורק אם שני האופרנדים הם שקריים. כאן אנו רואים במידה מסוימת את אותה תמונה כמו במקרה של המפעיל &, אבל בדיוק ההפך. כלומר, אם לפחות אופרנד אחד נכון , אז a | bמובטח שהביטוי נכון ללא קשר לערך של האופרטור השני. אם &זה מתנהג כמו כפל לוגי, אז OR הוא חיבור לוגי, אם אתה מדמיין שאמת הוא 1 ושקר הוא 0. רק זכרו שחיבור לוגי עובד אחרת מחיבור רגיל. 1 + 1 במקרה זה שווה לא ל-2, אלא ל-1 (המספר 2 פשוט לא קיים במערכת הזו). לפעמים ניתוק מובן כמקסימום של 0 ו-1, ובמקרה זה, אם אופרנד אחד לפחות שווה ל-1 ( true ), נקבל בדיוק אמת . OR טבלת אמת, הידועה גם בתור התוצאה של האופרטור |:
א ב א | ב
נָכוֹן נָכוֹן נָכוֹן
נָכוֹן שֶׁקֶר נָכוֹן
שֶׁקֶר נָכוֹן נָכוֹן
שֶׁקֶר שֶׁקֶר שֶׁקֶר
OR לוגי, המכונה גם ניתוק, לדוגמה:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a | b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a | c);
       System.out.println((2 < 5) | false); // expression (2 < 5) is true, which means that for any second operand we get a true result
       System.out.println((2 > 5) | true);

   }
}
תוֹצָאָה:

false
true
true
true
אם נשתמש באופרטור המותנה OR - ||במקום |, נקבל בדיוק את אותה תוצאה, אבל, כמו במקרה של AND מותנה &&, הוא יפעל מבחינה כלכלית: אם "נתקל" באופרנד הראשון השווה ל- true , הערך של האופרנד השני אינו מסומן, אך מיד התוצאה נכונה .

XOR Java - לוגי בלעדי OR - אופרטור ^

XOR, תוספת מודולו 2, XOR לוגי, חיסור לוגי, ניתוק קפדני, השלמה סיבית... לאופרטור ^יש הרבה שמות באלגברה בוליאנית. התוצאה של החלת אופרטור זה על שני אופרנדים תהיה נכונה אם האופרנדים שונים ושקר אם האופרנדים זהים. לכן, נוח להשוות אותו עם הפחתת אפסים ( שקר ) ואחדים ( נכון ). טבלת אמת XOR, הידועה גם בתור התוצאה של האופרטור ^:
בוליאנית א בוליאנית ב א^ב
נָכוֹן נָכוֹן שֶׁקֶר
נָכוֹן שֶׁקֶר נָכוֹן
שֶׁקֶר נָכוֹן נָכוֹן
שֶׁקֶר שֶׁקֶר שֶׁקֶר
דוגמא:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a ^ b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a ^ c);
       System.out.println((2 < 5) ^ false);
       System.out.println((2 > 5) ^ true);
   }
}
תוֹצָאָה:

false
false
true
true

עדיפות של פעולות לוגיות

כמו במתמטיקה, בתכנות, לאופרטורים יש סדר ביצוע ספציפי כשהם מופיעים באותו ביטוי. לאופרטורים Unary יש יתרונות על פני בינאריים, וכפל (אפילו לוגי) על פני חיבור. דירגנו אופרטורים לוגיים גבוה יותר ברשימה, ככל שהעדיפות שלהם גבוהה יותר:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
בואו נסתכל על דוגמאות. לצירוף ולניתוק ( &ו |) יש עדיפות שונה:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println(a | b & c);
}
אם היינו ממשיכים משמאל לימין, כלומר להחיל תחילה את האופרטור |ולאחר מכן - &, היינו מקבלים את הערך false . אבל למעשה, אם תפעיל את התוכנית הזו, אתה תהיה בטוח שהפלט יהיה נכון , שכן לאופרטור AND הלוגי &תהיה עדיפות גבוהה יותר מאופרטור OR לוגי |. כדי למנוע בלבול, אתה צריך לזכור שמה &שמתנהג כמו כפל |ומה שמתנהג כמו חיבור. אתה יכול לשנות את סדר העדיפות. פשוט השתמש בסוגריים, בדיוק כמו במתמטיקה בבית הספר. בואו נשנה מעט את קוד הדוגמה שלנו:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println((a|b)&c);
}
מה קורה? תחילה אנו משתמשים בחיבור לוגי בסוגריים, ולאחר מכן בכפל. התוצאה תהיה שקרית .

ביטויים לוגיים מורכבים

כמובן, אנחנו יכולים לשלב ביטויים בוליאניים ואופרטורים. בואו נזכור את הביטוי מתחילת המאמר:
(a | b) | (c < 100) & !(true) ^ (q == 5)
עכשיו זה לא נראה כל כך מפחיד. בואו נכתוב תוכנית שמציגה את הערך שלה, לאחר שקבענו בעבר את הערכים של a, b, сו q. דוגמה לחישוב הערך של ביטוי בוליאני מורכב
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       int c = 25;
       int q = 2;
       System.out.println((a|b) | (c < 100) & !(true)^(q == 5));
   }
}
הערה:המשתנה qשלנו הוא מסוג int, אבל q == 5זה ביטוי בוליאני, והוא שווה ל- false , שכן למעלה אתחולנו עם qהמספר 2. אותו הדבר עם המשתנה c. מספר זה שווה ל-25, אבל (c < 100) הוא ביטוי בוליאני השווה ל- true . התוצאה של תוכנית זו:

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

אופרטורים ביטוויזיים (באופניים).

בתחילת המאמר, הזכרנו כי האופרטורים &, |ויכולים ^לשמש ביחס לסוגי מספרים שלמים של Java. במקרה זה הם אופרטורים סיביים. הם נקראים גם סיביות, מכיוון שספרה אחת היא סיבית אחת, ופעולות אלו פועלות במיוחד עם ביטים. כמובן, הם עובדים קצת אחרת מאופרטורים לוגיים, וכדי להבין בדיוק איך, צריך לדעת מהי מערכת מספרים בינארית. אם אתה לא יודע על זה כלום או ששכחת לגמרי, אנו מציעים לך קודם לקרוא את המאמר Java: bits and bytes , ולהזכיר לכל השאר שבמערכת המספרים הבינארית יש רק שתי ספרות - 0 ו-1, וכל הנתונים במחשב מיוצג בדיוק עם שימוש באפסים ואחדים מותנים. כל אחד מהמספרים שאנו רגילים אליהם (עשרוני; עבורם יש 10 ספרות שונות מ-0 עד 9, איתן אנו כותבים מספרים כלשהם) ניתן לייצג במערכת המספרים הבינארית. ניתן להמיר מספר עשרוני לבינארי באמצעות חלוקה רציפה לעמודה באמצעות בסיס מערכת המספרים (2). שאריות החלוקה בכל שלב, כתובות בסדר הפוך, יתנו לנו את המספר הבינארי הרצוי. הנה, למשל, ההמרה של המספר העשרוני 103 לייצוג בינארי: פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 3

מערכת מספרים בינאריים בקורס JavaRush

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

בנוסף ל- &, |ו- ^Java משתמשת גם באופרטורים סיביים:
  • ~ אופרטור שלילה סיבית
  • >>העבר ימינה בצורה חלקית
  • >>>העברה ימינה לא חתומה
  • <<העבר שמאלה בצורה חלקית
למתחילים, אופרטורים סיביים נראים מאוד מבלבלים ומלאכותיים. לרוב הם לא מבינים בשביל מה הם צריכים, למעט פתרון בעיות חינוכיות. למעשה, ניתן להשתמש בהם לכל הפחות כדי לארגן חלוקה וכפל יעילים, ואנשי מקצוע משתמשים בהם לקידוד/פענוח, הצפנה ויצירת מספרים אקראיים.

אופרטורים Bitwise &, | ו-^

בואו נסתכל על דוגמה לאופן הפעולה של המפעילים הללו. נניח שיש לנו שני מספרים שלמים:
int a = 25;
int b = 112; 
עלינו להחיל עליהם שלוש פעולות &ולהציג |את ^התוצאה על המסך. הנה קוד התוכנית:
public class Solution {
   public static void main(String[] args) {

       int a = 25;
       int b = 112;

       int res1 = a & b;
       int res2 = a | b;
       int res3 = a ^ b;

       System.out.println("a & b = " + res1);
       System.out.println("a | b = " + res2);
       System.out.println("a ^ b = " + res3);

   }
}
התוצאה של התוכנית היא כדלקמן:

a & b = 16
a | b = 121
a ^ b = 105
אם אתה לא מבין מה קורה, התוצאה נראית מאוד מאוד מסתורית. למעשה, הכל פשוט יותר ממה שזה נראה. אופרטורים סיביים "רואים" את מספרי האופרנד בצורה הבינארית שלהם. ואז הם מיישמים אופרטורים לוגיים &, |או ^על הספרות (סיביות) המתאימות של שני המספרים. אז, עבור &הסיביות האחרון של הייצוג הבינארי של המספר 25 מצטבר באופן הגיוני לסיביות האחרון של הייצוג הבינארי של המספר 112, הסיביות הלפני אחרונות עם הלפני אחרון, וכן הלאה: פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 4ניתן לאתר את אותו היגיון ב- מקרה של |ו ^. פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 5

הסט ביט שמאלה או ימינה

ישנם מספר אופרטורים של משמרת סיביות ב-Java. האופרטורים הנפוצים ביותר <<הם ו >>. הם מסיטים את הייצוג הבינארי של מספר שמאלה או ימינה, בהתאמה, ובמקרה של תזוזה ימינה, תוך שמירה על הסימן (נסביר להלן מה המשמעות של שימור הסימן). יש עוד מפעיל משמרת ימינה >>>. זה עושה את אותו הדבר אבל >>לא שומר את השלט. אז בואו נסתכל על העבודה שלהם באמצעות דוגמה. int a = 13 a << 1מעביר את כל הסיביות של הייצוג הבינארי של המספר a שמאלה ב-1 סיביות. כדי לפשט, בואו נציג את המספר 13 בצורה בינארית כ-0000 1101. למעשה, מספר זה נראה כך: 00000000 00000000 00000000 00001101, מכיוון ש-Java intמקצה 4 בתים או 32 ביטים למספרים. עם זאת, זה לא משחק תפקיד בדוגמה, אז בדוגמה זו ניקח בחשבון את המספר שלנו כ-one-byte. פעולות לוגיות ב-Java.  פעולות Bitwise ב-Java - 6הביט שהתפנה מימין מלא באפסים. כתוצאה מפעולה זו, נקבל את המספר 26. a << 2הוא מעביר את כל הסיביות של הייצוג הבינארי של המספר aשמאלה ב-2 סיביות, ושתי הסיביות המתפנות מימין מתמלאות באפסים. כתוצאה מכך נקבל את המספר 52. a << 3התוצאה תהיה 104... שימו לב לתבנית? העברה סיבית aשמאלה ב-n עמדות עובדת כמו הכפלת מספר aב-2 בחזקת n. כך גם לגבי מספרים שליליים. זה -13 << 3ייתן את התוצאה -104. a >> nמעביר את הייצוג הבינארי של מספר n מיקומים ימינה. לדוגמה, 13 >> 1 הופך את המספר 1101 למספר 0110, כלומר 6. והתוצאה 13 >> 2תהיה 3. כלומר, בעצם, כאן אנו מחלקים את המספר ב-2 בחזקת n, כאשר n הוא מספר ההזמרות ימינה, אבל עם אזהרה אחת: אם המספר הוא אי זוגי, במהלך פעולה זו נראה שאנו מאפסים את הסיביות האחרונה של המספר. אבל עם שליליים המצב שונה במקצת. נניח, נסה לבדוק מה התוכנית תפיק אם תבקש ממנה לבצע פעולה -13 >> 1. אתה תראה את המספר -7, לא -6, כפי שאתה עשוי לחשוב. זה קורה בגלל האופן שבו מספרים שליליים מאוחסנים ב-Java ושפות תכנות אחרות. הם מאוחסנים במה שנקרא קוד משלים. במקרה זה, הספרה המשמעותית ביותר (זו משמאל) ניתנת לשלט. במקרה של מספר שלילי, הספרה המשמעותית ביותר היא 1.

קוד נוסף

בואו ניקח בחשבון את המספר int a = 13. אם בתוכנה תדפיסו את הייצוג הבינארי שלו לקונסולה באמצעות הפקודה System.out.println(Integer.toBinaryString(a));, אז נקבל 1101. למעשה, זהו סימון קיצור, מכיוון שמספר הסוג intתופס 4 בתים בזיכרון, כך שהמחשב "רואה" אותו יותר ככה:

00000000 00000000 00000000 00001101
הספרה המשמעותית ביותר היא אפס, מה שאומר שיש לנו מספר חיובי. כדי להמיר לקוד נוסף:
  1. אנו כותבים את המספר -13 במה שנקרא "קוד ישיר". לשם כך, שנה את הספרה המשמעותית ביותר של המספר ל-1.
    תוצאת הפעולה:

    
    10000000 0000000 0000000 00001101
  2. לאחר מכן, נהפוך את כל הביטים (נשנה 0 ל-1, ו-1 ל-0) מלבד סיבית הסימן. למעשה, כבר שינינו את זה.
    תוצאה של הפעולה:

    
    11111111 11111111 11111111 11110010

    (כן, אפשר לשלב את שלבים 1 ו-2, אבל עדיף לחשוב על זה כך)

  3. הוסף 1 למספר המתקבל.
    תוצאת הפעולה:

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

11111111 11111111 11111111 11110011
סיביות אחת ימינה, וכתוצאה מכך רצף הביטים הבא:

11111111 11111111 11111111 11111001
אם נמיר את המספר הזה לקוד ישיר (כלומר, קודם נחסר את 1, ואז נהפוך את כל הביטים מלבד הראשון) נקבל את המספר:

10000000 00000000 00000000 00000111
או -7. כעת, לאחר שהבנו את מפעיל המשמרת הימנית משמרת השלטים, יתברר במה הוא שונה מהמפעיל >>>. a >>> n- פעולה זו היא תזוזה ללא סימן, כלומר, היא מסיטה את הייצוג הבינארי של מספר aימינה ב-n סיביות, אבל ממלאת את n הסיביות שהתפנו משמאל לא באחדים, כמו האופרטור >>, אלא באפסים. בוא נעשה את הפעולה -13 >>> 1. יש לנו כבר את המספר -13בהשלמה של שניים:

11111111 11111111 11111111 11110011
על ידי הזזה ימינה ב-1 סיביות ומילוי הסיביות הפנויות באפס, נקבל את המספר הבא:

01111111 11111111 11111111 11111001
מה נותן את המספר בסימון עשרוני 2147483641.

אופרטור שלילה ביטוויזית ~

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

11111111 11111111 11111111 11110011
פעולת השלילה הסיבית ~13פשוט תהפוך את הערך של כל סיביות. כתוצאה מכך אנו מקבלים:

00000000 00000000 00000000 00001100
או 12בצורה עשרונית.

מסקנות קצרות

  • כל האופרטורים הלוגיים חלים על ביטויים בוליאניים, כלומר אלה שניתן לומר שהם נכונים או שקריים .
  • Если операторы &, | or ^ применяются к числам, речь идёт уже не о логических операциях, а о побитовых. То есть оба числа переводятся в двоичную систему и к этим числам побитово применяют операции логического сложения, умножения or вычитания.
  • В математической логике операторам & и | соответствуют конъюнкция и дизъюнкция.
  • Логическое И похоже на умножения 1 (true) и 0 (false).
  • Логическое ИЛИ напоминает поиск максимума среди 1 (true) и 0 (false).
  • Для побитового отрицания целого числа a используется операция ~a.
  • Для логического отрицания булевского выражения a используется операция !a.
  • Отрицательные числа хранятся и обрабатываются в дополнительном codeе.
  • Поразрядный сдвиг вправо может сохранять знак (>>), а может — не сохранять (>>>).
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION