부울 연산자의 차이점 : & 대 && 및 | 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.