3방향 비교

컴퓨터 과학에서 **3방향 비교**(three-way comparison)는 전순서를 가진 타입에 속하는 두 값 A와 B를 가져와 수학적 삼분법의 법칙에 따라 단일 연산으로 A B인지 여부를 결정한다. 이는 함수 (C의 `strcmp`와 같은), 메서드 (자바의 `compareTo`와 같은), 또는 연산자 (펄, PHP, C++의 **우주선 연산자** ``와 같은)로 구현될 수 있다.
# 기계 수준 계산
많은 프로세서에는 기본 타입에 대한 이러한 연산을 지원하는 명령어 집합이 있다.access-date = September 22, 2025 일부 머신은 부호-크기 또는 1의 보수 표현(부호화된 숫자 표현 참조)에 기반한 부호 있는 정수를 가지며, 둘 다 구별되는 양수 및 음수 0을 허용한다. 이는 일관된 전순서가 채택되는 한 삼분법을 위반하지 않는다: −0 = +0 또는 −0 NaN, x = NaN이 모두 거짓이다.
# 고급 언어

## 기능
C에서 `strcmp` 및 `memcmp` 함수는 각각 문자열과 메모리 버퍼 간에 3방향 비교를 수행한다. 첫 번째 인수가 두 번째 인수보다 사전적으로 작으면 음수를 반환하고, 인수가 같으면 0을 반환하며, 그렇지 않으면 양수를 반환한다. 이러한 "차이의 부호"를 반환하는 규칙은 표준 정렬 함수 `qsort`에 의해 임의의 비교 함수로 확장되며, `qsort`는 비교 함수를 인수로 받아들이고 이를 준수하도록 요구한다. 펄 (숫자 비교에만 해당하며, `cmp` 연산자는 문자열 사전 비교에 사용됨), PHP (버전 7부터), 루비, Apache Groovy에서 "우주선 연산자" ``는 A B인지 여부에 따라 각각 −1, 0, 또는 1의 값을 반환한다. 파이썬 2.x의 `cmp`(3.x에서 제거됨), OCaml `compare`, 코틀린 `compareTo` 함수는 동일한 것을 계산한다. 하스켈 표준 라이브러리에서 3방향 비교 함수 `compare`는 `Ord` 클래스의 모든 타입에 대해 정의된다; 이 함수는 `Ordering` 타입을 반환하며, 그 값은 `LT` (작음), `EQ` (같음), 및 `GT` (큼)이다:Data.Ord data Ordering = LT | EQ | GT 많은 객체 지향 프로그래밍 언어에는 객체와 다른 주어진 객체 간에 3방향 비교를 수행하는 3방향 비교 함수가 있다. 예를 들어, 자바에서 `Comparable` 인터페이스를 구현하는 모든 클래스에는 음의 정수, 0, 또는 양의 정수를 반환하거나 `NullPointerException`을 던지는 (객체 중 하나 또는 둘 다 `null`인 경우) `compareTo` 메서드가 있다. 마찬가지로, .NET 프레임워크에서 `IComparable` 인터페이스를 구현하는 모든 클래스에는 이러한 `CompareTo` 메서드가 있다. C++에서 3방향 비교가 가능한 모든 클래스는 `std::compare_three_way`, `std::strong_order`, `std::weak_order`, 또는 `std::partial_order`의 인스턴스의 매개변수가 될 수 있다. 자바 버전 1.5부터는 아래에 언급된 산술 오버플로와 같은 계산 문제 없이 차이를 알 수 있다면 `Math.signum` 정적 메서드를 사용하여 동일한 것을 계산할 수 있다. 많은 컴퓨터 언어는 함수의 정의를 허용하므로 compare(A,B)를 적절하게 고안할 수 있지만, 문제는 내부 정의가 어떤 종류의 3방향 구문을 사용할 수 있는지 또는 반복 테스트에 의존해야 하는지 여부이다. 3방향 비교 연산자나 메서드가 이미 없는 경우 3방향 비교를 구현할 때 A = B 및 A B와 같이 두 가지 비교를 결합하는 것이 일반적이다. 원칙적으로 컴파일러는 이 두 표현식을 하나의 비교 다음에 여러 결과 테스트로 대체할 수 있다고 추론할 수 있지만, 이 최적화에 대한 언급은 해당 주제에 대한 텍스트에서 찾을 수 없다. 어떤 경우에는 A와 B를 빼고 결과의 부호를 검사하여 3방향 비교를 시뮬레이션할 수 있으며, 숫자의 부호를 검사하는 특수 명령어를 활용할 수 있다. 그러나 이 경우 A와 B의 타입이 잘 정의된 차이를 가져야 한다. 고정 폭 부호 있는 정수는 뺄셈 시 오버플로될 수 있고, 부동소수점 숫자는 정의되지 않은 부호를 가진 NaN 값을 가지며, 문자열은 전체 순서에 해당하는 차이 함수가 없다. 기계 수준에서는 오버플로가 일반적으로 추적되며 뺄셈 후 순서를 결정하는 데 사용될 수 있지만, 이 정보는 일반적으로 상위 수준 언어에서는 사용할 수 없다. 프로그래밍 언어에서 제공하는 3방향 조건문의 한 경우, 포트란의 현재는 더 이상 사용되지 않는 3방향 산술 IF 문은 산술 표현식의 부호를 고려하고 결과의 부호에 따라 이동할 세 개의 레이블을 제공한다: IF (expression) negative,zero,positive C 및 관련 언어의 일반 라이브러리 함수 strcmp는 문자열에 대한 3방향 사전식 비교이지만, 이러한 언어는 다른 데이터 타입에 대한 일반적인 3방향 비교를 지원하지 않는다.
## 우주선 연산자
숫자에 대한 3방향 비교 연산자 또는 "우주선 연산자"는 펄, 루비, Apache Groovy, PHP, Eclipse Ceylon, C++에서 ``로 표기되며 우주선 연산자라고 불린다.accessdate=26 September 2014 C++에서는 C++20 개정판이 우주선 연산자 ``를 추가하여, 두 값이 같은지, 작은지, 큰지, 또는 순서가 없는지를 인코딩하는 값을 반환하며, 비교의 엄격성에 따라 다른 타입을 반환할 수 있다.허브 서터는 "Consistent Comparison"이라는 제목의 논문에서 `` 구문으로 C++ 표준에 3방향 비교 연산자를 추가할 것을 제안했다. "Consistent Comparison"을 참조하라. 2017년 11월 C++20 초안에 성공적으로 병합되었다. 이 이름의 유래는 랜들 L. 슈왈츠가 HP BASIC 스타 트렉 게임의 우주선을 연상시켰기 때문이라고 한다.title=Spaceship history (was Re: [dart-misc] DEP meeting notes) 다른 코더는 스타워즈 사가에 나오는 다스 베이더의 타이 파이터와 비슷하게 생겼기 때문에 그렇게 명명되었다고 제안했다.title=Super Spaceship Operator PHP 예시: echo 1 1; // 0 echo 1 2; // -1 echo 2 1; // 1 C++ 예시: 1 1; // std::strong_ordering::equal로 평가됨 1 2; // std::strong_ordering::less로 평가됨 2 1; // std::strong_ordering::greater로 평가됨
## 복합 데이터 타입
3방향 비교는 2방향 비교와 달리 기본이 아닌 데이터 타입에 대한 사전식 비교를 쉽게 구성하고 구축할 수 있는 속성을 가지고 있다. 다음은 펄의 구성 예시이다. sub compare($$) { my ($a, $b) = @_; return $a->{unit} cmp $b->{unit} || $a->{rank} $b->{rank} || $a->{name} cmp $b->{name}; } 펄에서 `cmp`는 문자열에 사용되며, ``는 숫자에 사용된다는 점에 유의하라. 2방향 동등 코드는 덜 간결하지만 반드시 덜 명확한 것은 아니다. 위 코드는 `||` 연산자의 단락 평가와 펄에서 0이 거짓으로 간주된다는 사실을 활용한다. 결과적으로 첫 번째 비교가 동일하면 (0으로 평가되므로) 두 번째 비교로 "넘어가고", 비영(non-zero) 값을 찾거나 끝에 도달할 때까지 계속된다. 파이썬, 루비, 하스켈 등을 포함한 일부 언어에서는 목록 비교가 사전식으로 이루어지므로, 위 예시처럼 값을 원하는 순서로 목록에 넣으면 비교 체인을 만들 수 있다. 예를 들어 루비에서는 다음과 같다. [a.unit, a.rank, a.name] [b.unit, b.rank, b.name]C++에서는:std::tie(a.unit, a.rank, a.name) std::tie(b.unit, b.rank, b.name)
## SQL 조인 연산자
일부 SQL 방언에서는 ``가 둘 다 null인 경우 피연산자를 일치시키는 null-안전 조인 연산자로 사용된다.https://dev.mysql.com/doc/refman/8.4/en/comparison-operators.html#operator_equal-to
# 내용주
Notelist