오늘 수업에서는 Java Bitwise Operators에 대해 알아보고 사용 방법의 예를 살펴보겠습니다. 당신은 아마 "비트"라는 단어에 익숙할 것입니다. 그렇지 않다면 그것이 무엇을 의미하는지 기억해 봅시다 :) 비트는 컴퓨터에서 가장 작은 정보 단위입니다. 그것의 이름은 이진수 에서 온다 . 비트는 1 또는 0의 두 숫자 중 하나로 표현할 수 있습니다. 1과 0을 기반으로 하는 특별한 이진수 시스템이 있습니다. 우리는 여기서 수학적 정글을 탐구하지 않을 것입니다. Java의 모든 숫자는 이진 형식으로 변환될 수 있습니다. 이렇게 하려면 래퍼 클래스를 사용해야 합니다.
비트 연산자 - 1
예를 들어 다음은 int 에 대해 이를 수행하는 방법입니다 .

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
콘솔 출력: 101010110 1010 10110(쉽게 읽을 수 있도록 공백을 추가했습니다)은 십진법으로 숫자 342입니다. 우리는 실제로 이 숫자를 0과 1의 개별 비트로 분해했습니다. 비트에 대해 수행되는 연산을 bitwise 라고 합니다 .
  • ~ - 비트별 NOT.
이 연산자는 매우 간단합니다. 숫자의 각 비트를 전달하고 비트를 뒤집습니다. 0은 1이 되고 1은 0이 됩니다. 이것을 숫자 342에 적용하면 다음과 같이 됩니다. 101010110은 이진수로 표현되는 342입니다 .

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
콘솔 출력: 169 169는 친숙한 십진법의 결과( 010101001 )입니다 :)
  • & - 비트 AND
보시다시피 논리 AND( && )와 상당히 유사해 보입니다. && 연산자 는 두 피연산자가 모두 true인 경우에만 true를 반환합니다. Bitwise &는 비슷한 방식으로 작동합니다. 두 숫자를 비트 단위로 비교합니다. 비교는 세 번째 숫자를 생성합니다. 예를 들어, 숫자 277과 432를 살펴보겠습니다. 110110000은 이진수 표현된 277입니다 . 이것은 AND 연산자이기 때문에 두 비트가 모두 1인 경우에만 결과가 1이 됩니다. 다른 경우에는 결과가 0입니다. 100010101 && 연산자 먼저 두 숫자의 첫 번째 비트를 비교한 다음 두 번째 비트, 세 번째 비트 등을 비교합니다. 보시다시피 숫자의 해당 비트가 모두 1인 경우는 두 가지뿐입니다(첫 번째 및 다섯 번째 비트). 다른 모든 비교는 0을 생성했습니다. 그래서 결국 우리는 숫자 10001000을 얻었습니다. 십진법에서는 숫자 272에 해당합니다. 확인해 봅시다.

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
콘솔 출력: 272
  • | - 비트 OR.
이 연산자는 같은 방식으로 작동합니다. 두 숫자를 비트 단위로 비교합니다. 이제 비트 중 적어도 하나가 1이면 결과는 1입니다. 동일한 숫자(277 및 432)를 살펴보겠습니다. 100010101 | 110110000 _______________ 110110101 - 결과 | 연산자 여기서 우리는 다른 결과를 얻습니다. 0으로 남아 있는 유일한 비트는 두 숫자 모두에서 0이었던 비트입니다. 결과는 숫자 110110101입니다. 십진법에서는 숫자 437에 해당합니다. 확인해 보겠습니다.

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
콘솔 출력: 437 모든 것을 올바르게 계산했습니다! :)
  • ^ - 비트별 XOR(배타적 OR)
우리는 아직 이 연산자를 만나지 못했습니다. 그러나 그것에 대해 복잡한 것은 없습니다. 일반적인 OR 연산자와 유사합니다. 한 가지 차이점이 있습니다. 일반 OR은 적어도 하나의 피연산자가 참이면 참을 반환합니다. 그러나 반드시 하나일 필요는 없습니다. 두 피연산자가 모두 참이면 결과도 참입니다. 그러나 배타적 OR은 피연산자 중 정확히 하나만 true인 경우에만 true를 반환합니다. 두 피연산자가 모두 참이면 일반 OR은 참("적어도 하나는 참")을 반환하지만 XOR은 거짓을 반환합니다. 이것이 배타적 OR이라고 불리는 이유입니다. 이전 비트 연산자가 어떻게 작동하는지 알면 277 ^ 432 를 쉽게 계산할 수 있습니다. 하지만 한 번 더 함께 파헤쳐 봅시다 :) 100010101 ^ 110110000 _______________ 010100101 - ^ 의 결과연산자 이것이 우리의 결과입니다. 두 숫자에서 동일한 비트는 0을 생성합니다("유일한" 테스트가 실패했음을 의미). 그러나 0-1 또는 1-0 쌍을 이루는 비트는 1이 됩니다. 결과는 숫자 010100101입니다. 십진법에서는 숫자 165에 해당합니다. 계산이 올바른지 확인해 보겠습니다.

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
콘솔 출력: 165 Super! 모든 것이 우리가 생각한 그대로입니다 :) 이제 비트 시프트 연산자에 대해 알아볼 시간입니다. 그 이름은 그 자체로 말합니다. 우리는 어떤 숫자를 취하고 그 비트를 왼쪽이나 오른쪽으로 움직입니다 :) 어떻게 보이는지 봅시다:

왼쪽으로 이동

왼쪽으로의 비트 이동은 << 로 표시됩니다 . 예를 들면 다음과 같습니다.

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
이 예에서 숫자 x = 64를 값이라고 합니다. 우리가 이동할 값의 비트입니다. 비트를 왼쪽으로 이동합니다( << 연산자 의 방향으로 추측할 수 있음 ) 이진법에서 숫자 64 = 1000000 숫자 y = 3 을 이동 거리라고 합니다. 이동 거리는 오른쪽/왼쪽으로 숫자 x 의 비트를 이동하려는 비트 수를 나타냅니다 . 이 예에서는 왼쪽으로 3비트 이동합니다. 이동 과정을 보다 명확하게 보려면 그림을 보십시오. 이 예에서는 int 를 사용합니다. 정수는 컴퓨터 메모리에서 32비트를 차지합니다. 이것이 우리의 원래 숫자 64의 모습입니다.
비트 연산자 - 2
이제 각 비트를 가져와 문자 그대로 왼쪽으로 3자리 이동합니다.
비트 연산자 - 3
우리가 얻은 것을 살펴보십시오. 보시다시피 모든 비트가 이동했고 범위 가장자리에서 또 다른 3개의 0이 추가되었습니다. 3, 3만큼 이동했기 때문입니다. 10만큼 이동했다면 10개의 0이 추가되었을 것입니다. 따라서 x << y 라는 표현은 "숫자 x 의 비트를 왼쪽으로 y만큼 이동"을 의미합니다. 식의 결과는 1000000000이며 십진법으로 512입니다. 점검 해보자:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
콘솔 출력: 512 Spot on! 이론적으로 비트는 끝없이 이동할 수 있지만 숫자가 int 이기 때문에 사용할 수 있는 이진수는 32개뿐입니다. 이 중 7개는 이미 64개(1000000)가 점유하고 있습니다. 따라서 왼쪽으로 27자리를 이동하면 데이터 유형의 범위를 벗어나 손실되는 유일한 자리가 됩니다. 0 만 남을 것입니다!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
콘솔 출력: 0 예상대로 하나는 사용 가능한 32비트를 넘어 이동하여 사라졌습니다. 우리는 0으로만 구성된 32비트 숫자로 끝났습니다.
비트 연산자 - 4
당연히 이것은 십진법에서 0에 해당합니다. 다음은 왼쪽으로의 이동을 기억하는 간단한 규칙입니다. 왼쪽으로 이동할 때마다 숫자에 2를 곱합니다. 비트 111111111 << 3의 그림 없이 다음 식을 계산해 봅시다. 숫자 111111111에 2를 곱해야 합니다 . 결과적으로 888888888이 됩니다. 몇 가지 코드를 작성하고 확인하겠습니다.

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
콘솔 출력: 888888888

오른쪽으로 이동

이 작업은 >> 로 표시됩니다 . 같은 일을 하지만 방향이 다릅니다! :) 우리는 바퀴를 재발명하지 않을 것입니다. 동일한 int 64 로 시도해 봅시다 .

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
비트 연산자 - 5
비트 연산자 - 6
오른쪽으로 2만큼 이동한 결과 숫자의 극단에 있는 두 개의 0이 범위를 벗어나 손실됩니다. 우리는 10000을 얻습니다. 이것은 십진법의 숫자 16에 해당합니다. 콘솔 출력: 16 다음은 오른쪽으로의 이동을 기억하기 위한 간단한 규칙입니다. 오른쪽으로의 각 이동은 2로 나누고 나머지는 버립니다. 예를 들어, 35 >> 2 는 35를 2로 번 나누어 나머지를 버려야 함을 의미합니다. 35/2 = 17(나머지 1 버리기) 17/2 = 8(나머지 1 버리기) 8과 같아야 합니다. 확인해 보겠습니다.

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
콘솔 출력: 8

Java의 연산자 우선 순위

코드를 작성하고 읽는 동안 여러 작업을 결합한 표현식을 자주 보게 됩니다. 실행 순서를 이해하는 것이 매우 중요합니다(그렇지 않으면 결과에 놀랄 수 있습니다). Java에는 많은 작업이 있으므로 각 작업은 특수 테이블에 할당되었습니다.

연산자 우선순위

연산자 상위
접미사 expr++ expr--
단항 ++expr --expr +expr ~ !
곱셈 * / %
첨가물 + -
옮기다 << >> >>>
관계형 < > <= >= 인스턴스의
평등 == !=
비트 AND &
비트 배타적 OR ^^
비트 포함 OR |
논리적 AND &&
논리적 OR ||
세 개 한 벌 ? :
과제 = += -= *= /= %= &= ^= |= <<= >>= >>>=
모든 작업은 우선 순위를 고려하여 왼쪽에서 오른쪽으로 수행됩니다. 예를 들어, 우리가 쓴다면

int x  = 6 - 4/2;
그런 다음 나눗셈 연산( 4/2 )이 먼저 수행됩니다. 두 번째로 나오더라도 우선 순위가 더 높습니다. 괄호와 대괄호는 최대 우선 순위를 나타냅니다. 당신은 아마 학교에서 그것을 기억할 것입니다. 예를 들어 식에 추가하면

int x  = (6 - 4)/2;
그런 다음 빼기가 괄호로 묶여 있으므로 빼기가 먼저 수행됩니다. 논리 && 연산자의 우선 순위는 다소 낮으므로(표 참조) 일반적으로 마지막에 옵니다. 예를 들어:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
이 식은 다음과 같이 실행됩니다.
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
다음으로 비교 연산자가 실행됩니다.
  • 4 > 3 = 참

boolean x = true && 144 <= 119;
  • 144 <= 119 = 거짓

boolean x = true && false;
그리고 마지막으로 AND 연산자( && )가 마지막으로 실행됩니다.

boolean x = true && false;
boolean x = false;
예를 들어 더하기( + ) 연산자는 != (같지 않음) 비교 연산자 보다 우선 순위가 높습니다 . 따라서 식에서

boolean x = 7 != 6+1;
6+1 작업이 먼저 수행된 다음 7 != 7 검사(거짓으로 평가됨), 마지막으로 결과(거짓)를 변수 x에 할당합니다(할당은 일반적으로 모든 연산자의 우선 순위가 가장 낮습니다. 참조 ) . 탁자). 휴! 엄청난 교훈이었지만 해냈습니다! 이 단원이나 이전 단원 중 일부를 완전히 이해하지 못했다고 걱정하지 마십시오. 앞으로 이러한 주제에 대해 두 번 이상 다룰 것입니다. 논리 및 수치 연산에 대한 몇 가지 CodeGym 강의입니다. 우리는 곧 이것들을 다루지 않을 것이지만 지금 그것들을 읽는 것이 나쁠 것은 없습니다.