티스토리 뷰

팀 코드리뷰 시간에 비트 연산자로만 알고 있었던 |와 &를 논리 연산자처럼 사용할 수 있다는 말에 호기심을 가지게 되었습니다.
"어떻게 가능할까? 그리고 논리 연산자인 ||, &&와는 어떤 차이가 있을까?”라는 궁금증이 생겨서 정리해 보았습니다.


비트 연산자

|와 &는 비트 연산자입니다.

  • |
    "0001 | 0000 == 0001”이 성립합니다. 즉, 하나의 비트 비교시 하나라도 1이라면 1이 됩니다.
  • &
    |와는 다르게 두 비트 모두가 1인 경우만 1이 됩니다.
    즉, "0101 & 0100 == 0100”이 됩니다.


논리 연산자

|| 와 &&는 논리 연산자입니다.

  • ||(or)
    하나라도 true인 경우 true를 반환합니다. 즉, “true || false == true”가 됩니다.
  • &&(and)
    모두 true인 경우만 true를 반환합니다. 즉, “true && true == true, true && false == false”가 됩니다.


비트 연산자를 논리 연산자로 사용

Java에서는 비트 연산자를 논리 연산자로 사용이 가능합니다.

public class OrOperationExample {
    public static void main(String[] args) {
        if (alwaysFalse() | alwaysTrue()) {
            System.out.println("false | true case");
        }
        System.out.println();

        if (alwaysTrue() | alwaysFalse()) {
            System.out.println("true | false case");
        }
        System.out.println();

        if (alwaysFalse() || alwaysTrue()) {
            System.out.println("false || true case");
        }
        System.out.println();

        if (alwaysTrue() || alwaysFalse()) {
            System.out.println("true || false case");
        }
        System.out.println();
    }

    public static boolean alwaysTrue() {
        System.out.println("Always True");
        return true;
    }

    public static boolean alwaysFalse() {
        System.out.println("Always False");
        return false;
    }
}
public class AndOperationExample {
    public static void main(String[] args) {
        if ((alwaysFalse() & alwaysTrue()) == false) {
            System.out.println("false & true case");
        }
        System.out.println();

        if ((alwaysTrue() & alwaysFalse()) == false) {
            System.out.println("true & false case");
        }
        System.out.println();

        if ((alwaysFalse() && alwaysTrue()) == false) {
            System.out.println("false && true case");
        }
        System.out.println();

        if ((alwaysTrue() && alwaysFalse()) == false) {
            System.out.println("true && false case");
        }
        System.out.println();
    }

    public static boolean alwaysTrue() {
        System.out.println("Always True");
        return true;
    }

    public static boolean alwaysFalse() {
        System.out.println("Always False");
        return false;
    }
}
Always False
Always True
false | true case

Always True
Always False
true | false case

Always False
Always True
false || true case

Always True
true || false case
Always False
Always True
false & true case

Always True
Always False
true & false case

Always False
false && true case

Always True
Always False
true && false case

Java에서 실행결과를 보면 |와 ||, &와 &&는 같은 결과값을 가지는 것을 알 수 있습니다.

Java에서 비트 연산자를 논리 연산자로 사용할 수 있는 이유

Java에서 if문에는 boolean(또는 Boolean) 타입만 조건으로 사용할 수 있습니다.
|와 &를 if문에서 사용할 수 있는 이유는 위에서 테스트한 코드에서 알 수 있듯이 결과 값이 ||와 &&를 사용했을 때와 값이 같기 때문입니다.

00000001(true) | 00000000(false) == 00000001(true)
00000001(true) & 00000000(false) == 00000000(false)
true || false == true
true && false == false

C나 C++에서는 Java처럼 사용할 수 없는데요. 그 이유는 아래와 같습니다.
if(int & int) 구문에서 int 값이 양수이면 참, 0이면 false라고 예상이 될텐데, if(2&4)의 경우 "100 & 010 == 000"이 되기 때문에 false가 되기 때문에 사용할 수 없습니다. 다만 if(bool & bool)이라면 사용은 가능합니다.

비트 연산자(|, &) VS 논리 연산자(||, &&)

Java에서는 두 연산자에 대한 결과가 같기 때문에 비트 연산자를 논리 연산자로 사용할 수 있음을 샘플코드로 확인하였습니다.(위 코드 참조)
그렇다면 동작방식도 같을까요? 샘플코드의 결과 값을 확인해 보면 차이가 있음을 알 수 있습니다.

예를 들어 alwaysTrue() | alwaysFalse()와 alwaysTrue() || alwaysFalse()를 비교해 보겠습니다.

Always True
Always False
true | false case
Always True
true || false case

비트 연산자에서는 alwaysFalse()가 실행되었으나, 논리 연산자에서는 alwaysFalse()가 실행되지 않았습니다.
Or(||) 연산자의 경우 하나라도 True라면 결과 값이 True이기 때문에 첫번째 조건이 True라면 두 번째 조건과는 상관없이 True이기 때문에 Java에서는 비교 구문을 실행하지 않게 됩니다. 종합해 보면 비트 연산자의 경우는 조건문을 다 수행한다면 논리 연산자는 결과에 영향을 주지 않는다면 실행하지 않음을 알 수 있습니다.

alwaysTrue() || alwaysFalse()에서 alwaysFalse() 구문을 실행하지 않는 것을 Short-circuit(https://en.wikipedia.org/wiki/Short-circuit_evaluation)이라고 합니다.


참고



'Programing > Java' 카테고리의 다른 글

Mybatis에서 resultType에 Primitive Type은 괜찮을까?  (0) 2016.10.04
Java Collection Framework  (0) 2016.09.30
IBATIS CacheModel  (0) 2016.09.26
Exception Propagation  (0) 2016.07.28
Java 로그에서 StackTrace 가 생략되는 현상  (0) 2016.04.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함