
참고
자바의 정석
논리 연산자
논리 연산자는 2개의 조건이 결합된 경우는 논리 연산자를 사용하여 사용한다.
보통 관계 혹은 비교 연산자와 함께 많이 사용하며 연산결과가 true 혹은 false를 반환한다.
논리 연산자 - &&, ||, !
- 논리 연산자 '&&'는 AND에 해당하며, 두 피연산자가 모두 true일 때만 true를 반환한다.
- 논리 연산자 '||'는 OR에 해당하며, 두 피연산자중 어느 한쪽만 true여도 true를 결과로 얻는다.
- 논리 연산자는 피연산자로 boolean형 또는 boolean형 값을 결과로 하는 조건식만을 허용한다.
|| (OR) : 피연산자 중 어느 한쪽만 true이면, true를 결과로 얻는다.
&& (AND) : 피연산자 양쪽 모두 true이어야 true를 결과로 얻는다.
| x | y | x || y | x && y |
|---|
| true | true | true | true |
| true | false | true | false |
| false | true | true | false |
| false | false | false | false |
💡 참고
단락 회로 평가 (short circuit evaluation)
- 논리 곱은 두 피연산자가 모두 true일때만 결과가 true
- 앞의 항이 false이면 뒤 항의 결과를 평가하지 않아도 false
- 논리 합은 두 피연산자 모두 fasle일때만 결과가 false
- 앞의 항이 true이면 뒤 항의 결과를 평가하지 않아도 true
논리 부정 연산자 !
- 이 연산자는 피연산자가 true이면 false를, false면 true를 반환
- 이 연산자를 반복적으로 적용하면 참과 거짓을 반복적으로 적용되므로, 토글버튼을 논리적으로 구현이 가능하다.
- 논리 부정연산자가 주로 사용하는 곳은 조건문이나 반복문에 조건식이다.
비트 연산자 & | ^ ~ << >>
- 비트 연산자는 피연산자를 비트단위로 논리 연산한다. 단, 피연산자는 실수는 허용하지 않으며, 정수만 허용한다.
| (OR 연산자): 피연산자 중 한쪽의 값이 1이면 1을 결과로 얻고, 그외는 0으로 얻는다.
& (AND 연산자): 피연산자 양 쪽이 모두 1이어야만 1을 결과로 얻는다. 그외에는 0을 얻는다.
^ (XOR 연산자): 피연산자의 값이 서로 다를 때만 1을 결과로 얻는다. 같을 때에는 0을 얻는다.
| x | y | x | y | x & y | x ^ y |
|---|
| 1 | 1 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 0 | 1 | 1 | 0 | 1 |
| 0 | 0 | 0 | 0 | 1 |
- 비트 OR 연산자 '|'는 주로 특정 비트의 값을 변경할 때 사용한다.
- 비트 AND 연산자 '&'는 주로 특정 비트의 값을 뽑아낼 때 사용한다.
- 비트 XOR 연산자 '^'는 두 피연산자의 비트가 다를때만 1이된다. 그리고 같은 값으로 두고 XOR연산을 수행하면 원래의 값으로 돌아오는 특징이 있어서 간단한 암호화에 사용된다.
- 비트 연산에도 피연산자의 타입을 일치시키는 '산술 변환'이 일어난다.
비트 전환 연산자 ~
- 이 연산자는 피연산자를 2진수로 표현했을 때, 0은 1로 1은 0으로 바꾼다. 논리부정 연산자 '!'와 유사하다.
- 비트 전환 연산자 '~'에 의해 비트 전환이 되고 나면 부호있는 타입의 피연산자는 부호가 반대로 변경된다.
- 비트 전환 연산자는 피연산자의 타입이 int 타입보다 작은 범위면 int로 자동 형변환 후에 연산하기 때문에 8자리 2진수로 표현했어도 결과는 32자리 2진수가 나온다.
- 참고로 위의 원칙때문에 쉬프트 연산자를 2번연속 써도 int형 타입으로 나온다.
쉬프트 연산자 << >>
- 이 연산자는 피연산자의 각 자리 (2진수일때)를 오른쪽 (>>) 혹은 왼쪽 (<<)으로 이동한다고 해서 쉬프트 연산자라고 불린다.
- 예를 들어 8 << 2는 10진수 8을 2진수로 변환하여 왼쪽으로 2자리 이동한다는 말이다.
- << 연산같은 경우 부호에 상관없이 각 자리를 왼쪽으로 이동시키며 빈 칸을 0으로만 채우면 되지만, >> 연산자는 오른쪽으로 이동시키기 때문에 부호있는 정수는 부호를 유지시키기 위해 왼쪽 피연산자가 음수인 경우 빈자리를 1로 채운다. 물론, 양수일때는 0으로 채운다.
- 쉬프트 연산자는 좌측 피연산자가 int보다 작은 타입이면 타입을 int로 자동 형변환이 된다. 그러나, 쉬프트 연산자는 다른 이항 연산자와 달리 피연산자의 타입을 일치시킬 필요가 없으므로 우측 피연산자에는 산술 변환이 일어나지 않는다.
x << n은 x * (2^n)의 결과와 같다.
x >> n은 x / (2^n)의 결과와 같다.
- 그럼 여기서 궁금한 사항이 쉬프트 연산을 안 쓰고 곱셉이나 나눗셈을 하면 되면 안될까? 굳이 왜 복잡한 쉬프트 연산을 써야할까?
- 이유는 바로 속도차이다. 쉬프트 연산이 속도가 굉장히 빠르다. 하지만 가독성이 곱셈, 나눗셈보다 현저히 떨어질 것이다. 그래서 결론은 되도록 곱셈이나 나눗셈을 사용하고 속도에 굉장히 민감한 프로그램은 쉬프트 연산을 사용하자.