부울 연산자의 차이점 : & 대 && 및 | vs ||


답변:


134

비트 AND 및 비트 OR 연산자입니다.

int a = 6; // 110
int b = 4; // 100

// Bitwise AND    

int c = a & b;
//   110
// & 100
// -----
//   100

// Bitwise OR

int d = a | b;
//   110
// | 100
// -----
//   110

System.out.println(c); // 4
System.out.println(d); // 6

입력을 기반으로 한 연산자의 다양한 동작과 관련하여 Java 언어 사양 ( 15.22.1 , 15.22.2 ) 에서 적절한 섹션을 지적한 Carlos에게 감사드립니다 .

실제로 두 입력이 모두 부울이면 연산자는 부울 논리 연산자로 간주 되며 다음이 안전하지만 단락되지 않는다는 점을 제외하면 &&조건부 및 ( ) 및 조건부 또는 ( ||) 연산자 와 유사하게 작동 합니다. :

if((a != null) && (a.something == 3)){
}

이것은 아니다:

if((a != null) & (a.something == 3)){
}

"단락"은 작업자가 모든 조건을 검사 할 필요는 없음을 의미합니다. 위의 예에서, &&경우에만 두 번째 조건을 검사 할 a수 없습니다 null(그렇지 않으면 전체 문이 false를 반환합니다, 어쨌든 조건에 따라 조사 할 논쟁 것)의 문 있도록 a.something예외를 발생하지 않을 것이다, 또는 "안전한 것으로 간주됩니다 . "

&작업자는 항상 상기의 예에서, 상기 구문의 모든 조건을 검사 a.something할 때 평가 될 수 a사실 A는 null예외를 제기 값.


1
명확하게하고 싶었습니다. & 둘 다 1 인 경우에만 1을 반환합니까? 그래서 101 & 001은 001이 될까요? 권리?
— gideon

@giddy @Jonathon-그 상황을 더 잘 보여주기 위해 내 가치를 업데이트했습니다.
— Justin Niessner

불완전 : 논리 연산자 (부울 용)이기도합니다.
— user85421

1
@ Carlos- 아니요. 여전히 비트 연산자입니다. 비 단락 논리 연산자와 동일하게 동작합니다. 차이가 있습니다.
— Justin Niessner

4
비 단락 논리 연산자는 무엇입니까? 연산자 & 및 | (OP에서 요청)은 "Integer Bitwise Operators"(JLS 15.22.1) 및 "Boolean Logical Operators"(JLS 15.22.2)입니다. 아니면 Java 언어 사양이 잘못 되었습니까?
— user85421

108

두 연산자의 논리적 의미에 대해 이야기하고 있다고 생각합니다. 여기에 테이블 이력서가 있습니다.

boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE

단락 평가 , 최소 평가 또는 McCarthy 평가 (John McCarthy 이후)는 일부 프로그래밍 언어에서 두 번째 인수가 실행되거나 첫 번째 인수가 값을 결정하는 데 충분하지 않은 경우에만 평가되는 일부 부울 연산자의 의미입니다. 표현식 : AND 함수의 첫 번째 인수가 거짓으로 평가되면 전체 값은 거짓이어야합니다. OR 함수의 첫 번째 인수가 true로 평가되면 전체 값이 true 여야합니다.

안전하지 않음 은 연산자가 항상 절의 모든 조건을 검사 함을 의미하므로 위의 예에서 1 / x는 x가 실제로 0 값일 때 평가되어 예외가 발생할 수 있습니다.


1
@Torres- "단락"및 "안전"을 설명하여 답변을 확장하십시오. 또한 "배타적 또는"및 "논리적 아님"도 "단락되지 않음"입니까? 그리고 왜 "논리적 논리가 아닌 논리"대신 "논리적 논리"라고 불릴까요? 그리고 "논리적 NOT"이 "논리적 AND"와 "논리적 OR"로 그룹화되지 않은 이유는 무엇입니까? 좋은 대답이지만 작업이 필요합니다.
— tfmontague 2011

@tfmontague, 나는 단락이 무엇을 의미하는지 설명했습니다 (이 답변을 편집하여) .. 내 편집이 "동료 검토"되기를 기다리고 있습니다.
— Taslim Oseni

단락되지 않는 것에 대해 "안전하지 않은"것은 무엇입니까? 단락을 사용하는 것보다 더 안전하지 않습니까? btw : "단락"이라는 용어를 실제로 설명하지 않습니다. 즉, "not short-circuit"에서 모든 부품이 먼저 평가 된 다음 부울 연산이 적용되고, short-circuit에서는 평가가 중지되고, 첫 번째 표현식이 조건을 충족하면 (a || b)는 그렇지 않습니다. a가 참이고 또는 연산이 b가 무엇이든 상관없이 참을 반환하면 b를 평가합니다.
— SCI

26

여기에 많은 답변이 있다는 것을 알고 있지만 모두 약간 혼란스러워 보입니다. 그래서 Java oracle 학습 가이드에서 몇 가지 조사를 한 후 && 또는 &를 사용할 때 세 가지 시나리오를 생각해 냈습니다. 세 가지 시나리오는 논리 AND , 비트 AND 및 부울 AND 입니다.

논리적 AND : 논리 AND (일명 조건부 AND)는 && 연산자를 사용합니다 . 단락 된 의미입니다. 왼쪽 피연산자가 거짓이면 오른쪽 피연산자가 평가되지 않습니다.
예:

int x = 0;
if (false && (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); // "0"

위의 예에서 x의 콘솔에 인쇄 된 값은 if 문의 첫 번째 피연산자가 false이므로 java가 계산할 필요가 없으므로 (1 == ++ x) x가 계산되지 않기 때문에 0이됩니다.

비트 AND : 비트 AND는 & 연산자를 사용합니다 . 값에 대해 비트 연산을 수행하는 데 사용됩니다. 이진수에 대한 연산을 살펴보면 무슨 일이 일어나는지 보는 것이 훨씬 쉽습니다. 예 :

int a = 5;     //                    5 in binary is 0101
int b = 12;    //                   12 in binary is 1100
int c = a & b; // bitwise & preformed on a and b is 0100 which is 4

예에서 볼 수 있듯이 숫자 5와 12의 이진 표현이 정렬되면 비트 AND preformed는 두 숫자의 동일한 숫자가 1 인 이진 숫자 만 생성합니다. 따라서 0101 & 1100 == 0100. 십진수로 5 & 12 == 4입니다.

부울 AND : 이제 부울 AND 연산자가 비트 AND 및 논리 AND 모두에 대해 유사하고 다르게 작동합니다. 나는 두 개의 부울 값 (또는 비트) 사이에 비트 AND를 미리 형성하는 것으로 생각하고 싶으므로 & 연산자를 사용합니다 . 부울 값은 논리식의 결과 일 수도 있습니다.

논리 AND와 매우 유사하게 true 또는 false 값을 반환하지만 논리 AND와 달리 단락되지 않습니다. 그 이유는 비트 AND를 수행하려면 왼쪽 및 오른쪽 피연산자의 값을 모두 알아야하기 때문입니다. 예를 들면 다음과 같습니다.

int x = 0;
if (false & (1 == ++x) {
    System.out.println("Inside of if");
}
System.out.println(x); //"1"

이제 if 문이 실행되면 왼쪽 피연산자가 false 인 경우에도 (1 == ++ x) 표현식이 실행됩니다. 따라서 x에 대해 인쇄 된 값은 증가했기 때문에 1이됩니다.

이것은 논리 OR (||), 비트 OR (|) 및 부울 OR (|)에도 적용됩니다. 이것이 약간의 혼란을 없애기를 바랍니다.


to preform that bitwise AND, it must know the value of both left and right operands이것은 나에게 옳지 않은 것 같습니다. 를 수행하려면 BITWISE AND왼쪽 피연산자가 인 경우 결과를 파악하기 위해 오른쪽 피연산자를 알 필요가 없습니다 FALSE. 당신이 설명하는 것은 정확하지만 추론하면 상태는 적어도 나에게, 그래서 ..하지 않는 것
— Koray 투 케이

7

연산자 && 및 || 단락입니다. 즉, 왼손 표현식의 값이 결과를 결정하기에 충분하면 오른손 표현식을 평가하지 않습니다.


7
-1은 그가 이미 알고있는 것을 말하고 그가 실제로 묻는 질문에 대답하지 않은 것에 대해.
— Alnitak

5

& 및 | &&와 같은 결과를 제공하고 || 연산자. 차이점은 항상 && 및 ||로 표현의 양쪽을 평가한다는 것입니다. 첫 번째 조건이 결과를 결정하기에 충분한 지 평가를 중지하십시오.


1
Wrong .... 첫 번째 조건이 참인 경우에만 반환 &&하는 동안 두 결과를 모두 평가 ||합니다.
— Buhake Sindi

1
어? &&는 왼쪽이 이미 true로 평가 된 경우 표현식의 오른쪽 만 평가합니다. 그렇지 않으면 첫 번째 거짓이 결과가 참일 수 없음을 의미하기 때문에 평가를 중단합니다. jguru.com/faq/view.jsp?EID=16530
— Brian Scott

1
( 2 & 4 )가 평가 false반면 ( 2 && 4 )가 평가 true. 그게 정확히 같은 결과일까요?
— Piskvor는

1
@Piskvor-Java가 아닙니다! 2 & 4결과는 부울이 아닌 정수입니다 (이 경우 0). 2 && 4컴파일되지 않고 && 부울 만 허용합니다. 0이 아닌 : 자바는 논리 값과의 int를 혼합 할 수 없습니다 false, false... 제로는 아니다
— user85421

1
@BuhakeSindi 틀 렸습니다. 내용은 &&단지 두 번째 피연산자를 평가 첫 번째 피연산자 인 경우 true.
— Marquis of Lorne

2

Java에서 단일 연산자 &, |, ^,! 피연산자에 따라 다릅니다. 두 피연산자가 모두 int이면 비트 연산이 수행됩니다. 둘 다 부울이면 "논리"연산이 수행됩니다.

두 피연산자가 일치하지 않으면 컴파일 시간 오류가 발생합니다.

이중 연산자 &&, || 단일 피연산자와 유사하게 작동하지만 두 피연산자는 모두 조건식이어야합니다. 예를 들면 다음과 같습니다.

if ((a <0) && (b <0)) {...} 또는 유사하게 if ((a <0) || (b <0)) {...}

출처 : 자바 프로그래밍 언어 4 판



1

비트 AND 및 비트 OR 연산자는 항상 조건부 AND 및 조건부 OR이 동일한 표현식에서 사용되기 전에 평가된다는 것을 아는 것이 유용 할 수 있습니다.

if ( (1>2) && (2>1) | true) // false!

1
평가 순서가 아닌 운영자 우선 순위를 의미합니까? 차라리 실제 코드에서 사용되는 우선 순위 차이를 보지 않겠습니다. 이를 위해 비트 연산자보다는 괄호를 사용하십시오.
— John Dvorak 2013 년

1

&&; || 논리 연산자입니다 .... 단락

&; | 부울 논리 연산자입니다 .... 비 단락 회로

식 실행의 차이로 이동합니다. 비트 연산자는 좌변의 결과에 관계없이 양쪽을 모두 평가합니다. 그러나 논리 연산자를 사용하여 식을 평가하는 경우 오른손 식의 평가는 왼손 조건에 따라 달라집니다.

예를 들면 :

int i = 25;
int j = 25;
if(i++ < 0 && j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

그러면 i = 26이 인쇄됩니다. j = 25, 첫 번째 조건이 false이므로 오른쪽 조건에 관계없이 결과가 false이므로 오른쪽 조건이 무시됩니다. (단락)

int i = 25;
int j = 25;
if(i++ < 0 & j++ > 0)
    System.out.println("OK");
System.out.printf("i = %d ; j = %d",i,j);

그러나 이것은 i = 26을 인쇄합니다. j = 26,


0

Boolean & 연산자가 이 평가되면 두 피연산자가 모두 평가됩니다. 그런 다음 & 연산자가 피연산자에 적용됩니다.

&&를 포함하는 표현식 연산자가 이 평가 첫 번째 피연산자가 평가됩니다. 첫 번째 피연산자가 false로 평가되면 두 번째 피연산자의 평가를 건너 뜁니다.

첫 번째 피연산자가 true 값을 반환하면 두 번째 피연산자가 평가됩니다. 두 번째 피연산자가 true 값을 반환하면 && 연산자가 첫 번째 및 두 번째 피연산자에 적용됩니다.

유사 | 그리고 ||.


0

기본적인 차이는 있지만 그 &대부분에 비트 연산에 사용되는 long, int또는 byte이 마스크의 종류에 사용할 수있는 당신의 논리 대신에 그것을 사용하는 경우에도 결과는 다를 수 있습니다 &&.

차이는 일부 시나리오에서 더 두드러집니다.

  1. 일부 표현식을 평가하는 데 시간이 많이 걸립니다.
  2. 식 중 하나를 평가하는 것은 이전식이 참인 경우에만 수행 할 수 있습니다.
  3. 표현에 약간의 부작용이 있습니다 (의도적이든 아니든)

첫 번째 요점은 매우 간단하며 버그를 일으키지 않지만 시간이 더 걸립니다. 하나의 조건문에 여러 가지 다른 검사가있는 경우 더 저렴하거나 실패 할 가능성이 더 높은 검사를 왼쪽에 두십시오.

두 번째 요점은 다음 예를 참조하십시오.

if ((a != null) & (a.isEmpty()))

이것은 실패 null두번째 식을 평가하는 단계를 생성 같이 NullPointerException. 논리 연산자 &&는 게으르고 왼쪽 피연산자가 거짓이면 오른쪽 피연산자가 무엇이든 결과는 거짓입니다.

세 번째 요점의 예-트리거 또는 캐스케이드없이 DB를 사용하는 앱이 있다고 가정 해 보겠습니다. Building 객체를 제거하기 전에 Department 객체의 건물을 다른 건물로 변경해야합니다. 또한 작업 상태가 부울 (true = 성공)로 반환된다고 가정 해 보겠습니다. 그때:

if (departmentDao.update(department, newBuilding) & buildingDao.remove(building))

이는 두 식을 모두 평가하여 어떤 이유로 부서 업데이트가 실패하더라도 건물 제거를 수행합니다. 를 사용하면 &&의도 한대로 작동하고 첫 번째 실패 후 중지됩니다.

의 경우 a || b와 동일하며 !(!a && !b), atrue이면 중지 되며 더 이상 설명이 필요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.