부울 검사에 xor 연산자를 사용하는 것이 좋습니다? [닫은]


150

나는 개인적으로 같은 독점 또는 , ^이 때문에 간결의 여부를 확인의 맥락에서 의미가, 연산자. 나는 글 쓰는 것을 훨씬 좋아한다

if (boolean1 ^ boolean2)
{
  //do it
}

...보다

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

그러나 나는 종종 초보자뿐만 아니라 다른 숙련 된 Java 개발자들로부터 혼란스러워 보이고 때로는 비트 연산에만 사용해야하는 방법에 대한 의견을 얻습니다.

^운영자 의 사용에 관한 모범 사례에 대해 궁금합니다 .

답변:


298

!=대신 간단하게 사용할 수 있습니다 .


36
"!의 문제는 bool1 ^ bool2 ^ bool3 나보다 논리적으로 의미가 있습니다.bool1 != bool2 != bool3
BlueRaja-Danny Pflughoeft

4
뇌가 아파요. 따라서! = 잘못된 결과를 산출 할 수 있습니까?
vemv

27
@vemv, s에 !=대한 올바른 결과를 생성합니다 boolean(그러나 s에 대해서는 그렇지 않으므로 Boolean주의하십시오). 항상 예쁘지 (some != null) != (other != null)는 않습니다. 예를 들어 읽기가 쉽지 않습니다. 명시 적 부울로 부품을 추출하거나 !=별도의 방법으로 추출해야합니다 .
ivant

23
이유는 다음과 같습니다. a ^ b=> "a 또는 b이지만 둘 다 아님", a != b=> "a는 b와 같지 않습니다". (@RobertGrant가 말한 것). 그들은 XOR이 무엇인지 알고있는 경우에 대부분의 인간은 (... 당신은 컴퓨팅 분야에있어 알고 매우 유용하다) 쉽게 첫 번째를 이해하는 것
해롤드 R. 이슨

2
여기 HaroldR.Eason 중요한 하찮은 일에 속 태우고 @ : a != b> "A는 B와 동일하지 않다"=
마리오 Reutter

27

나는 당신이 당신의 자신의 질문에 대답했다고 생각합니다-사람들로부터 이상한 외모를 얻는다면 더 명확한 옵션을 사용하는 것이 더 안전합니다.

주석을 달아야 할 경우 더 자세한 버전으로 바꾸고 사람들이 처음에 질문하지 않도록하는 것이 좋습니다.


6
나는 당신을 주장 할 수 있습니다 (boolean1 && !boolean2) || (boolean2 && !boolean1). 실제 응용 프로그램 코드 를 심각하게 작성할 때, 당신은 저에게서 이상한 모습을 보게 될 것입니다 …
Holger

17

비슷한 대화를 많이하는 것으로 나타났습니다. 한편으로는 목표를 달성하는 작고 효율적인 방법이 있습니다. 반면에, 당신은 다른 팀원들이 이해할 수없는 것을 가지고 있기 때문에, 미래에 유지하기가 어렵습니다.

나의 일반적인 규칙은 사용되는 기술이 프로그래머가 일반적으로 알기를 기대하는 것이 합리적인지 묻는 것입니다. 이 경우 프로그래머가 부울 연산자를 사용하는 방법을 알고 있으므로 if 문에 xor를 사용하는 것이 좋습니다.

좋지 않은 것의 예로서, xor를 사용하여 임시 변수를 사용하지 않고 두 변수를 교환하는 트릭을 가져 가십시오. 그것은 모두가 익숙하지 않을 것이라고 생각하는 트릭이므로 코드 검토를 통과하지 못합니다.


14

예를 들어 댓글을 달면 괜찮을 것 같습니다 // ^ == XOR.


10

항상 함수로 감싸서 자세한 이름을 지정할 수 있습니다.

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

그러나 ^ 연산자가 무엇인지 Google에 대해 정말로 알지 못하는 사람에게는 어렵지 않을 것 같습니다. 처음으로 기억하기 어렵지 않습니다. 다른 용도를 요청 했으므로 비트 마스킹에 XOR을 사용하는 것이 일반적입니다.

XOR을 사용하여 세 번째 임시 변수를 사용하지 않고 두 변수의 값을 바꿀 수도 있습니다 .

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

다음은 XOR 스와핑과 관련된 Stackoverflow 질문 입니다.


6

나는 최근에 직장에서 JavaScript 프로젝트에서 xor를 사용하여 무슨 일이 있었는지 설명하기 위해 7 줄의 주석추가 했습니다. 그 상황에서 배타적 사용을위한 정당성 (용어의 하나 term1없는 두하지만 세 가지 값을 취할 수에 아래의 예) undefined, true또는 false다른 상태 ( term2) 일 수 true또는 false. 나는에 대한 추가 검사를 추가해야했습니다 undefined경우 만 XOR로, 다음은 첫 학기 첫 번째 부울로 평가되는 XOR 힘 때문에셔서 충분했다 undefined로 취급받을 false:

if (term1 ^ term2) { ...

결국 약간의 과잉 이었지만 어쨌든 일종의 이스터 에그로 보관하고 싶었습니다.


IMHO는 암시 적 변환에 의존하는 대신, 드물게 발생하는 상황에서 변환을 명시 적으로 만드는 것이 좋습니다 . 그리고 일반적으로 "정의되지 않은 상태로 허위로 처리"하는 것은 모든 언어에서 의심의 여지가 있습니다. Java에서는 tri-state 값을 사용하지 않았지만 C #에서는 bool? a값을 사용하여 명시 적으로 true를 테스트 할 수 있습니다 .Java에도 a == true비슷한 기술이 있습니까? C #에서 두 개의 bool?값이 주어지면 "null을 false로 처리"가됩니다 (a == true) ^ (b == true). 동등한 공식은 (a == true) != (b == true)입니다. 자바에서 비슷한 것을 할 수 있습니까?
ToolmakerSteve

5
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 

이 코드는 IMHO 단순화 될 수 있습니다 :

if(boolean1 != boolean2) 
{ 
  //do it 
} 

5

코드 명확성을 염두에두고 부울 검사에 XOR을 사용하는 것이 XOR 비트 연산자의 일반적인 사용법이 아니라고 생각합니다. 내 경험상 Java의 비트 XOR은 일반적으로 마스크 flag toggle동작 을 구현하는 데 사용됩니다 .

flags = flags ^ MASK;

Vipan Singla 의이 기사에서는 사용 사례에 대해 자세히 설명합니다.

예제에서와 같이 비트 XOR을 사용해야하는 경우 비트를 사용하는 이유를 이해하기 위해 비트 리터럴 청중조차도 트랙에서 멈추어야 할 가능성이 있기 때문에 사용 이유를 설명하십시오.


-1

나는 간결함으로 인해 "boolean1 ^ boolean2"표현을 개인적으로 선호합니다.

내가 당신의 상황에 있다면 (팀에서 일하고 있다면) "isDifferent (boolean1, boolean2)"와 같은 설명적인 이름을 가진 함수에 "boolean1 ^ boolean2"논리를 캡슐화하여 타협을 할 것입니다.

예를 들어 "boolean1 ^ boolean2"를 사용하는 대신 다음과 같이 "isDifferent (boolean1, boolean2)"를 호출합니다.

if (isDifferent(boolean1, boolean2))
{
  //do it
}

"isDifferent (boolean1, boolean2)"함수는 다음과 같습니다.

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

물론,이 솔루션에는 표면 상으로 외부 함수 호출을 사용하는 것이 포함되는데,이 함수 호출 자체는 Best Practices 정밀 검사의 대상이지만 자세한 표현 (및 못생긴) 표현 "(boolean1 &&! boolean2) || (boolean2 &&! boolean1) "!


-2

사용 패턴이 그것을 정당화한다면, 왜 그렇지 않습니까? 팀에서 시간이 지남에 따라 운영자를 즉시 ​​인식하지 못합니다. 인간은 항상 새로운 단어를 배웁니다. 왜 프로그래밍하지 않습니까?

내가 말할 수있는 유일한주의 사항은 "^"에 두 번째 부울 검사의 단락 의미가 없다는 것입니다. 단락 시맨틱이 실제로 필요한 경우 정적 util 메소드도 작동합니다.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}

16
xor로 가능한 단락이 보이지 않습니다. 결과를 평가하려면 a와 b를 모두 알아야합니다.
Thelema

7
또한 인수는 호출 시간에 평가되므로 단락이 발생하지 않습니다.
erikkallen

3
또한 xor는 시스템 수준에서 단일 작업이어야합니다.
오우거 시편 33

단락 평가와 지연 평가의 차이점을 찾아보아야 할 것입니다. 단기 통화 평가는 0으로 나누기와 같이 런타임 오류가 발생하는 호출을 방지하는 코드 스타일입니다. C에서 이것은“if (분모! = 0 && 분자 / 분모)”일 수 있으며, 그것은 자기 평가에 의해 제로에 의한 나누기를 막기 위해 게으른 평가를 사용합니다. 당신의 대답 또한 순전히 추측입니다.
Martin

2
솔직히 말해서 함수를 작성하는 프로그래머 xor는 xor 연산자가 수행하지만 정확히 원형 교차로 방식으로 방금 사용한 프로그래머보다 내 마음에 (특히 역량에 관한) 더 많은 질문을 제기 할 것 ^입니다.
Stijn de Witt

-3

! =는 두 변수를 비교해도 괜찮습니다. 그러나 여러 비교에서는 작동하지 않습니다.


-3

비트 연산자 인 xor는 다른 어떤 방법보다 훨씬 빠릅니다. 따라서 성능이 중요하고 확장 가능한 계산을 위해서는 xor가 필수적입니다.

나의 주관적인 개인적 견해 : 어떤 목적 으로든 부울에 대해 평등 (== 또는! =)을 사용하는 것은 절대적으로 금지되어 있습니다. 그것을 사용하면 기본 프로그래밍 윤리와 기본이 부족하다는 것을 알 수 있습니다. 혼란스러워 보이는 사람은 ^를 부울 대수의 기본으로 되돌려 보내야합니다 (여기에서 "신념의 강"으로 쓰려고 유혹했습니다).


1
JIT가 하나의 부울 식을 다른 부울 식으로 바꾸는 것과 같이 키홀 (작은) 최적화에 매우 능숙하다는 점을 제외하고.
David Leppik

1
또한 ^는 주로 부울 (논리) 연산자가 아니라 비트 연산자입니다. 부호 버그가있을 가능성이 있기 때문에 독자에게 속도를 늦추도록 지시합니다. ^를! =에 사용하면 C로 프로그래밍하면 정말 엉망이됩니다. 비트 연산자는 독자에게 (당신을 포함하여 코드를 디버깅하는 사람들) 신호를 느리게하고 부호 오류를 찾는 신호입니다. . 그리고 까다로울 수 있습니다. 예를 들어 C 또는 Python과 같이 Java의 %가 모듈로가 아니라는 것을 알고 있습니까? 한때 C, JavaScript 및 Python에서 동일하게 실행되었지만 Java에서는 실행되지 않는 코드 스 니펫이있었습니다.
David Leppik

6
이것은 어떻게 upvoted? 우선, Java XOR 및! =에서 [ stackoverflow.com/a/4175512/202504] (정확히 동일한 코드로) 컴파일되고 , 두 번째로 평등에 대한 어셈블러 테스트에서도 xor는 각각 단일 간단한 연산입니다. 진술서를 백업 할 번호가 있습니까?
jmiserez

-4
str.contains("!=") ^ str.startsWith("not(")

나보다 나아 보인다

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