3-5. 논리 연산자

Hyun Jun·2022년 1월 22일
0

자바의 정석

목록 보기
13/52
post-thumbnail
post-custom-banner

논리 연산자

두 개 이상의 조건식을 결합할 때 사용함. 피연산자는 boolean형이거나 boolean형을 결과로 하는 조건식이어야 함.

  • &&: AND 결합. 피연산자 양쪽 모두 true여야 true가 반환됨

  • ||: OR 결합. 피연산자 둘 중 하나만 true여도 true가 반환됨.

 

// x가 7 이상이고, 20 보다 작다.
x >= 7 && x < 20

// x가 3 보다 크거나, -3 보다 작다.
x > 3 || x < -3

&&||를 혼합하여 사용할 때, &&가 우선하므로 필요한 부분은 먼저 연산되도록 괄호 처리를 함.

// num이 3의 배수이거나 4의 배수이고, 7의 배수는 아니다.
( num % 3 == 0 || num % 4 == 0 ) && num % 7 != 0

 

효율적 연산 (short circuit evaluation)

논리 연산자는 가장 적은 연산으로 결과를 효율적이게 반환함.

  • ||(OR) 연산자의 경우, 좌측 피연산자가 true면 결과도 true이기 때문에 굳이 우측 피연산자는 평가하지 않음.

  • &&(AND) 연산자의 경우, 좌측 피연산자가 false면 결과도 false이기 때문에 굳이 우측 피연산자는 평가하지 않음.

 

따라서 연산 속도를 높이려면,

||의 좌변에 true일 확률이 높은 조건식을, &&의 좌변에 false일 확률이 높은 조건식을 놓아야 함.

 

논리 부정 연산자

피연산자 앞에 !를 붙이면 truefalse로, falsetrue로 바꿔줄 수 있음.

boolean isActive = false;
!isActive // true

 

비트 연산자

피연산자를 비트 단위로 논리 연산함. 피연산자를 2진수로 표현했을 때 각 자리의 수(0 또는 1)를 다음 규칙으로 평가함.
피연산자는 정수형과 문자형(char)만 허용.

  • & (AND): 피연산자 양쪽 모두 값이 1이면 결과는 1. 그 외의 경우 결과는 0

  • | (OR): 피연산자 중 한 쪽의 값이 1이면 결과는 1. 그 외의 경우 결과는 0

  • ^ (XOR): 피연산자의 값이 서로 다르면 결과는 1. 같을 때의 결과는 0

 

비트 연산자 |는 특정 비트의 값을 변경할 때 사용.

ex) 16진수 피연산자 0xAB의 마지막 4 bit를 F로 바꾸기

0xAB | 0xF

연산 과정:

0xAB : 1 0 1 0 1 0 1 1
 0xF : 0 0 0 0 1 1 1 1
----------------------
       1 0 1 0 1 1 1 1   16진수로 변환 -> 0xAF

 

비트 연산자 &는 특정 비트의 값을 추출할 때 사용.

ex) 16진수 피연산자 0xAB의 마지막 4 bit 값 알아내기

0xAB & 0xF

연산 과정:

0xAB : 1 0 1 0 1 0 1 1
 0xF : 0 0 0 0 1 1 1 1
----------------------
       0 0 0 0 1 0 1 1  -> 16진수로 변환 -> 0xB (마지막 4비트 값은 B 라는 것을 알 수 있음)

 

비트 연산자 ^는 암호화에 사용.

같은 값에 대해 2번 연산하면 원래 값으로 돌아옴

ex) 16진수 0xF를 encryption key로 삼아 피연산자 0xAB 암호화하기

0xAB ^ 0xF

연산 과정:

0xAB : 1 0 1 0 1 0 1 1
 0xF : 0 0 0 0 1 1 1 1
----------------------
       1 0 1 0 0 1 0 0  -> 16진수로 변환 -> 0xA4 (암호화 됨)

0xA4 : 1 0 1 0 0 1 0 0
 0xF : 0 0 0 0 1 1 1 1
----------------------
       1 0 1 0 1 0 1 1  -> 16진수로 변환 -> 0xAB (원래 값으로 돌아옴)

 

비트 전환 연산자

~를 피연산자 앞에 붙여주면, 피연산자를 2진수로 표현했을 때, 0은 1로 1은 0으로 바꿔줌.

~0xAB

연산 과정:

0xAB : 1 0 1 0 1 0 1 1
----------------------
       0 1 0 1 0 1 0 0 -> 16진수로 변환 -> 0x54

비트 전환 연산이 되면 부호 있는 타입은 부호 비트가 반대로 바뀌면서 부호가 반대가 됨.

정수 m의 1의 보수 + 1 = -m 이라는 것을 상기시켜보면, 정수 m의 1의 보수 = -m - 1 = ~m 임을 알 수 있음.

즉, 비트 전환 연산자를 사용하면 피연산자의 1의 보수를 얻을 수 있음.

실제로 0xAB는 10진수로 171이고, 0x54는 10진수로 -172임.

단, 위의 연산 과정 설명과는 달리 실제 연산 시에는 모두 32 자리의 int형으로 변환된 상태에서 연산됨.

응용: byte 정수 m에 비트 전환을 2번 한 ~~mm과 같은 수이면서 int형이 됨

 

쉬프트 연산자

a >> b(또는 a << b)는 피연산자 a의 2진수를 오른쪽(>>) 또는 왼쪽(<<)으로 b칸 만큼 움직인다는 뜻임.

int 보다 작은 좌측 피연산자는 int로 산술 변환됨. (우측 피연산자는 형 유지)

 

왼쪽(<<)으로 쉬프트:

자리 이동으로 저장범위를 벗어난 값은 버려지고 그 자리는 0으로 채워짐.

0xAB << 2

연산 과정:

0xAB : 1 0 1 0 1 0 1 1
   1 0 1 0 1 0 1 1      (좌측으로 2칸 이동함)
----------------------
       1 0 1 0 1 1 0 0 -> 16진수로 변환 -> 0xAC

 

오른쪽(>>)으로 쉬프트:

부호(-) 있는 정수는 부호를 유지하기 위해 빈 칸을 1로 채움

양수는 왼쪽으로 쉬프트 할 때처럼 빈 칸을 0으로 채움

 

결국 쉬프트 연산은 2진법에서의 자리 이동이므로 다음과 같은 효과를 지님.

x << n: x * 2n 과 같음

x >> n: x / 2n 과 같음

곱셈이나 나눗셈으로도 가능한 것인데 굳이 쉬프트를 제공하는 이유: 더 빠른 연산 속도

그러나 코드 가독성은 떨어지므로 성능만을 위해 사용하기엔 무리가 있음.

profile
Back-end Engineer 👨‍💻
post-custom-banner

0개의 댓글