מפעילי Java Bitwise

1. סקירה כללית

משתמשים במפעילים בשפת Java להפעלת נתונים ומשתנים.

במדריך זה נחקור מפעילי Bitwise וכיצד הם עובדים בג'אווה.

2. מפעילים סיביות

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

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

אופרטורים סיביות עובדים על שווה ערך בינארית למספרים עשרוניים ומבצעים בהם פעולות טיפין-טיפין לפי האופרטור הנתון:

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

בואו נבין עם דוגמא; בוא ניקח שניים מספרים שלמים:

ערך int1 = 6; ערך int2 = 5;

לאחר מכן, בוא נפעיל אופרטור OR או קצת על המספרים הבאים:

תוצאה int = 6 | 5;

כדי לבצע פעולה זו תחילה יחושב הייצוג הבינארי של מספרים אלה:

מספר בינארי של ערך 1 = 0110 מספר בינארי של ערך 2 = 0101

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

0110 0101 ----- 0111

לבסוף, התוצאה 0111 יומר בחזרה לעשרוני ששווה ל- 7:

תוצאה: 7

אופרטורים סיביות מסווגים עוד כמפעילי לוגיקה סיבית וסיבית. בואו נעבור על כל סוג.

3. מפעילים לוגיים סיבית

המפעילים הלוגיים סיביות הם AND (&), OR (|), XOR (^) ו- NOT (~).

3.1. סיבית אוֹ (|)

מפעיל OR משווה כל ספרה בינארית של שני מספרים שלמים ומחזיר 1 אם אחד מהם הוא 1.

זה דומה ל- || מפעיל לוגי המשמש עם בוליאנים. כאשר משווים שני בוליאנים התוצאה היא נָכוֹן אם אחד מהם הוא נָכוֹן. באופן דומה, הפלט הוא 1 כאשר אחד מהם הוא 1.

ראינו דוגמה למפעיל זה בסעיף הקודם:

@ מבט בטל ציבורי givenTwoIntegers_whenOrOperator_thenNewDecimalNumber () value2; assertEquals (7, תוצאה); 

בואו נראה את הייצוג הבינארי של פעולה זו:

0110 0101 ----- 0111

כאן אנו יכולים לראות ששימוש ב- OR, 0 ו -0 יביא ל -0, בעוד שכל שילוב עם לפחות 1 יביא ל -1.

3.2. סיבית AND (&)

אופרטור AND משווה כל ספרה בינארית של שני מספרים שלמים ומחזיר 1 אם שניהם 1, אחרת הוא מחזיר 0.

זה דומה למפעיל && עם בוליאני ערכים. כאשר הערכים של שניים בוליאנים הם נָכוֹן התוצאה של מבצע && היא נָכוֹן.

בואו נשתמש באותה דוגמה כמו לעיל, למעט כעת שימוש באופרטור & במקום | מַפעִיל:

@Test הציבור בטל givenTwoIntegers_whenAndOperator_thenNewDecimalNumber () {int value1 = 6; ערך int2 = 5; int result = value1 & value2; assertEquals (4, תוצאה); }

בואו נראה גם את הייצוג הבינארי של פעולה זו:

0110 0101 ----- 0100

0100 הוא 4 בעשרוני, לכן התוצאה היא:

תוצאה: 4

3.3. XOR Bitwise (^)

מפעיל ה- XOR משווה כל ספרה בינארית של שני מספרים שלמים ומחזיר 1 אם שני הביטים שהושוו שונים. המשמעות היא שאם סיביות משני המספרים השלמים הם 1 או 0 התוצאה תהיה 0; אחרת, התוצאה תהיה 1:

@Test הציבור בטל givenTwoIntegers_whenXorOperator_thenNewDecimalNumber () {int value1 = 6; ערך int2 = 5; int result = value1 ^ value2; assertEquals (3, תוצאה); }

והייצוג הבינארי:

0110 0101 ----- 0011

0011 הוא 3 בעשרוני, ולכן התוצאה היא:

תוצאה: 3

3.4. COMPLEMENT סיבית (~)

אופרטור Bitwise Not or Complement פשוט פירושו שלילת כל ביט של ערך הקלט. זה לוקח רק מספר שלם אחד וזה שווה ערך ל-! מַפעִיל.

אופרטור זה משנה כל ספרה בינארית של המספר השלם, כלומר כל 0 הופכים ל -1 וכולם 1 הופכים 0. ה! המפעיל עובד באופן דומה עבור בוליאני ערכים: זה הופך בוליאני ערכים מ נָכוֹן ל שֶׁקֶר ולהיפך.

בואו ונבין לדוגמא כיצד למצוא את השלמת המספר העשרוני.

בואו נעשה את השלמת הערך 1 = 6:

@Test הציבור בטל givenOneInteger_whenNotOperator_thenNewDecimalNumber () {int value1 = 6; int result = ~ value1; assertEquals (-7, תוצאה); }

הערך בינארי הוא:

ערך 1 = 0000 0110

על ידי יישום מפעיל המשלים, התוצאה תהיה:

0000 0110 -> 1111 1001

זהו ההשלמה של המספר העשרוני 6. ומכיוון שהסיבית הראשונה (השמאלית ביותר) היא 1 בינארי, המשמעות היא שהסימן הוא שלילי למספר המאוחסן.

כעת, מכיוון שהמספרים מאוחסנים כתוספת של 2, ראשית עלינו למצוא את השלמת 2 שלה ולאחר מכן להמיר את המספר הבינארי שהתקבל למספר עשרוני:

1111 1001 -> 0000 0110 + 1 -> 0000 0111

לבסוף, 0000 0111 הוא 7 בעשרוני. מכיוון שסיבית הסימן הייתה 1 כאמור לעיל, לכן התשובה המתקבלת היא:

תוצאה: -7

3.5. טבלת מפעילים סיבית

בואו נסכם את תוצאת המפעילים שראינו עד כה בטבלת השוואה:

A B A | B A&B A ^ B ~ A 0 0 0 0 0 1 1 0 1 0 1 0 0 1 1 0 1 1 1 1 1 1 0 0

4. מפעילי משמרת סיבית

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

בואו נראה את התחביר עבור אופרטורים אלה:

ערך 

הצד השמאלי של הביטוי הוא המספר השלם המוסט, והצד הימני של הביטוי מציין את מספר הפעמים שיש להזיז אותו.

מפעילי משמרות סיביות מסווגים עוד כמפעילי משמרת סיבית שמאלה וסיבית.

4.1. משמרת שמאלית חתומה [<<]

מפעיל משמרת שמאל מעביר את הסיביות שמאלה לפי מספר הפעמים שצוין בצד ימין של האופראנד. לאחר המשמרת השמאלית, החלל הריק מימין מלא ב- 0.

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

בואו ניקח את הערך 12 כערך הקלט.

כעת, נעביר אותו לפי 2 מקומות שמאלה (12 << 2) ונראה מה תהיה התוצאה הסופית.

המקבילה הבינארית של 12 היא 00001100. לאחר מעבר שמאלה בשני מקומות, התוצאה היא 00110000, שווה ערך ל 48 בעשרוני:

@Test ציבורי בטל givenOnePositiveInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int value = 12; int leftShift = ערך << 2; assertEquals (48, leftShift); } 

זה עובד באופן דומה עבור ערך שלילי:

@Test הציבור בטל givenOneNegativeInteger_whenLeftShiftOperator_thenNewDecimalNumber () {int ערך = -12; int leftShift = ערך << 2; assertEquals (-48, leftShift); }

4.2. משמרת ימינה חתומה [>>]

מפעיל משמרת ימני מעביר את כל הביטים ימינה. החלל הריק בצד שמאל מלא בהתאם למספר הקלט:

  • כאשר מספר קלט הוא שלילי, כאשר הסיבית השמאלית ביותר היא 1, אז הרווחים הריקים יתמלאו ב- 1
  • כאשר מספר קלט הוא חיובי, כאשר הסיבית השמאלית ביותר היא 0, אז הרווחים הריקים יתמלאו ב- 0

בואו נמשיך את הדוגמה באמצעות 12 כקלט.

כעת, נעביר אותו לפי 2 מקומות ימינה (12 >> 2) ונראה מה תהיה התוצאה הסופית.

מספר הקלט חיובי, אז לאחר העברת ימינה בשני מקומות, התוצאה היא 0011, שהיא 3 בעשרוני:

@Test הציבור בטל givenOnePositiveInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int value = 12; int rightShift = ערך >> 2; assertEquals (3, rightShift); }

כמו כן, עבור ערך שלילי:

@Test הציבור בטל givenOneNegativeInteger_whenSignedRightShiftOperator_thenNewDecimalNumber () {int ערך = -12; int rightShift = ערך >> 2; assertEquals (-3, rightShift); }

4.3. משמרת ימנית לא חתומה [>>>]

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

בואו ונזיז את אותו הערך של 12:

@Test הציבור בטל givenOnePositiveInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int value = 12; int unsignedRightShift = ערך >>> 2; assertEquals (3, unsignedRightShift); }

ועכשיו, הערך השלילי:

@Test הציבור בטל givenOneNegativeInteger_whenUnsignedRightShiftOperator_thenNewDecimalNumber () {int ערך = -12; int unsignedRightShift = ערך >>> 2; assertEquals (1073741821, unsignedRightShift); }

5. ההבדל בין סיביות למפעילים לוגיים

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

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

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

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

6. השתמש במקרים

כמה מקרי שימוש פוטנציאליים של מפעילים סיביות הם:

  • ערימות תקשורת שבהן הביטים הנפרדים בכותרת המצורפת לנתונים מסמנים מידע חשוב
  • במערכות משובצות להגדיר / לנקות / להחליף רק סיבית אחת אחת של רישום ספציפי מבלי לשנות את הסיביות הנותרות
  • להצפנת נתונים לבעיות בטיחות באמצעות מפעיל XOR
  • בדחיסת נתונים על ידי המרת נתונים מייצוג אחד למשנהו, כדי להפחית את כמות השטח שנצלה

7. מסקנה

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

כל דוגמאות הקוד במאמר זה זמינות באתר GitHub.


$config[zx-auto] not found$config[zx-overlay] not found