programing

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

nasanasas 2020. 8. 17. 09:07
반응형

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


나는 규칙을 알고 &&하고 ||있지만 무엇 &|? 예를 들어 설명해주세요.


비트 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예외를 제기 값.


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

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

여기에 많은 답변이 있다는 것을 알고 있지만 모두 약간 혼란스러워 보입니다. 그래서 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이됩니다.

Bitwise AND: Bitwise AND uses the & operator. It's used to preform a bitwise operation on the value. It's much easier to see what's going on by looking at operation on binary numbers ex:

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

As you can see in the example, when the binary representations of the numbers 5 and 12 are lined up, then a bitwise AND preformed will only produce a binary number where the same digit in both numbers have a 1. Hence 0101 & 1100 == 0100. Which in decimal is 5 & 12 == 4.

Boolean AND: Now the boolean AND operator behaves similarly and differently to both the bitwise AND and logical AND. I like to think of it as preforming a bitwise AND between two boolean values (or bits), therefore it uses & operator. The boolean values can be the result of a logical expression too.

It returns either a true or false value, much like the logical AND, but unlike the logical AND it is not short-circuited. The reason being, is that for it to preform that bitwise AND, it must know the value of both left and right operands. Here's an ex:

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

Now when that if statement is ran, the expression (1 == ++x) will be executed, even though the left operand is false. Hence the value printed out for x will be 1 because it got incremented.

This also applies to Logical OR (||), bitwise OR (|), and boolean OR (|) Hope this clears up some confusion.


The operators && and || are short-circuiting, meaning they will not evaluate their right-hand expression if the value of the left-hand expression is enough to determine the result.


& and | provide the same outcome as the && and || operators. The difference is that they always evaluate both sides of the expression where as && and || stop evaluating if the first condition is enough to determine the outcome.


In Java, the single operators &, |, ^, ! depend on the operands. If both operands are ints, then a bitwise operation is performed. If both are booleans, a "logical" operation is performed.

If both operands mismatch, a compile time error is thrown.

The double operators &&, || behave similarly to their single counterparts, but both operands must be conditional expressions, for example:

if (( a < 0 ) && ( b < 0 )) { ... } or similarly, if (( a < 0 ) || ( b < 0 )) { ... }

source: java programming lang 4th ed


& and | are bitwise operators on integral types (e.g. int): http://download.oracle.com/javase/tutorial/java/nutsandbolts/op3.html

&& and || operate on booleans only (and short-circuit, as other answers have already said).


Maybe it can be useful to know that the bitwise AND and bitwise OR operators are always evaluated before conditional AND and conditional OR used in the same expression.

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

&& ; || are logical operators.... short circuit

& ; | are boolean logical operators.... Non-short circuit

Moving to differences in execution on expressions. Bitwise operators evaluate both sides irrespective of the result of left hand side. But in the case of evaluating expressions with logical operators, the evaluation of the right hand expression is dependent on the left hand condition.

For Example:

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

This will print i=26 ; j=25, As the first condition is false the right hand condition is bypassed as the result is false anyways irrespective of the right hand side condition.(short circuit)

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

But, this will print i=26; j=26,


If an expression involving the Boolean & operator is evaluated, both operands are evaluated. Then the & operator is applied to the operand.

When an expression involving the && operator is evaluated, the first operand is evaluated. If the first operand evaluates to false, the evaluation of the second operand is skipped.

If the first operand returns a value of true then the second operand is evaluated. If the second operand returns a value of true then && operator is then applied to the first and second operands.

Similar for | and ||.


While the basic difference is that & is used for bitwise operations mostly on long, int or byte where it can be used for kind of a mask, the results can differ even if you use it instead of logical &&.

The difference is more noticeable in some scenarios:

  1. Evaluating some of the expressions is time consuming
  2. Evaluating one of the expression can be done only if the previous one was true
  3. The expressions have some side-effect (intended or not)

First point is quite straightforward, it causes no bugs, but it takes more time. If you have several different checks in one conditional statements, put those that are either cheaper or more likely to fail to the left.

For second point, see this example:

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

This fails for null, as evaluating the second expression produces a NullPointerException. Logical operator && is lazy, if left operand is false, the result is false no matter what right operand is.

Example for the third point -- let's say we have an app that uses DB without any triggers or cascades. Before we remove a Building object, we must change a Department object's building to another one. Let's also say the operation status is returned as a boolean (true = success). Then:

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

This evaluates both expressions and thus performs building removal even if the department update failed for some reason. With &&, it works as intended and it stops after first failure.

As for a || b, it is equivalent of !(!a && !b), it stops if a is true, no more explanation needed.

참고URL : https://stackoverflow.com/questions/4014535/differences-in-boolean-operators-vs-and-vs

반응형