단락 불리언 연산자
단락 불리언 연산자 (Short-circuit Boolean Operators)
if와 while 조건에서 스칼라로의 암묵적 변환과 결합하면, Octave의 요소별 불리언 연산자는 대부분의 논리 연산에 충분해요. 하지만 전체 참값이 정해지는 즉시 불리언 표현식의 평가를 멈추고 싶을 때가 있어요. Octave의 단락(short-circuit) 불리언 연산자가 그렇게 동작합니다. Octave 매뉴얼 8.5.2절을 정리해 볼게요.
본문
boolean1 && boolean2 — 표현식 boolean1이 평가되고 all (boolean1(:)) 연산과 동등한 것으로 스칼라로 변환돼요. boolean1이 논리 값이 아니면 값이 0이 아닐 때 참, 0일 때 거짓으로 간주합니다. boolean1이 배열이면 비어 있지 않고 모든 원소가 0이 아닐 때만 참으로 간주해요. boolean1이 거짓으로 평가되면 전체 표현식의 결과는 거짓입니다. 참이면 표현식 boolean2가 boolean1과 같은 방식으로 평가돼요. 그것이 참이면 전체 결과는 참, 그렇지 않으면 거짓입니다.
Warning: all (boolean1(:))을 평가하는 것과의 동등성에 대한 한 가지 예외는 boolean1이 빈 배열일 때예요. MATLAB 호환성을 위해 빈 배열의 참값은 항상 false라서, all ([])가 true임에도 [] && true는 false로 평가됩니다.
boolean1 || boolean2 — 표현식 boolean1이 평가되고 all (boolean1(:))과 동등한 것으로 스칼라로 변환돼요. boolean1이 논리 값이 아니면 0이 아닐 때 참, 0일 때 거짓. 배열이면 비어 있지 않고 모든 원소가 0이 아닐 때만 참. boolean1이 참으로 평가되면 전체 결과는 참이에요. 거짓이면 boolean2가 boolean1과 같은 방식으로 평가됩니다. 참이면 전체 결과 참, 그렇지 않으면 거짓.
Warning: 빈 행렬의 참값은 항상 false예요 (자세한 내용은 앞 항목 참고).
전체 참값을 정하기 전에 두 연산자를 모두 평가하지 않을 수도 있다는 사실이 중요할 수 있어요. 예를 들어 표현식 a && b++에서는 변수 a가 0이 아닐 때만 변수 b의 값이 증가합니다.
이것은 좀 더 간결한 코드를 쓰는 데 사용할 수 있어요. 예를 들어 다음처럼 쓸 수 있죠:
function f (a, b, c)
if (nargin > 2 && ischar (c))
...
존재하지 않는 인자를 평가하려는 시도를 피하기 위해 if 문을 두 개 써야 할 필요가 없어졌죠. 예를 들어 단락 기능이 없다면 이렇게 써야 해요:
function f (a, b, c)
if (nargin > 2)
if (ischar (c))
...
이렇게 쓰면:
function f (a, b, c)
if (nargin > 2 & ischar (c))
...
f를 인자 하나나 둘로 호출할 때 오류가 나요. Octave가 & 연산자의 두 연산자를 모두 평가하려고 하기 때문이죠.
MATLAB은 if와 while 문의 참 표현식에서 &와 | 연산자가 단락 동작하도록 하는 특별한 동작이 있어요. Octave도 호환을 위해 같은 동작을 하지만, 이렇게 &와 |를 쓰는 것은 강력히 권장되지 않고 경고가 발행됩니다. 대신 항상 단락 동작을 하는 &&와 || 연산자를 쓰세요.
마지막으로, 삼항 연산자(?:)는 Octave에서 지원되지 않아요. 단락이 중요하지 않다면 ifelse 함수로 대체할 수 있습니다.
merge / ifelse
M = merge (mask, tval, fval)
M = ifelse (mask, tval, fval)
mask의 값에 따라 true_val과 false_val의 원소를 병합해요. mask가 논리 스칼라면 다른 두 인자는 임의의 값일 수 있어요. 그렇지 않으면 mask는 논리 배열이어야 하고, tval, fval은 일치하는 클래스의 배열 또는 cell 배열이어야 해요. 스칼라 mask 경우엔 mask가 참이면 tval, 거짓이면 fval이 반환됩니다.
배열 mask 경우에는 tval과 fval 모두 스칼라이거나 mask와 같은 차원의 배열이어야 해요. 결과는 다음과 같이 구성됩니다:
result(mask) = tval(mask);
result(! mask) = fval(! mask);
mask는 임의의 숫자 타입일 수도 있고, 그 경우 먼저 logical로 변환됩니다.
Programming Note: ifelse는 merge의 별칭이고 서로 바꿔 쓸 수 있어요.
See also: logical, diff.
더 알아보기
- octave-element-by-element-boolean-operators — 요소별 불리언 연산자
- octave-comparison-ops — 비교 연산자
- octave-statements — 조건·반복문 (별도 문서)