Тришляхове порівняння
В інформатиці, тришляхове[1] порівняння приймає два значення A і B, що належать до лінійно впорядкованого типу і визначає A < B, A = B чи A > B за одну дію, у відповідності до математичного закону трихотомії.
У програмуванні
У мовах програмування C++ (починаючи з C++20), Ceylon, Groovy, Perl, PHP, Ruby оператор тришляхового порівняння має вигляд <=>
. Багато мов програмування мають функції з подібним призначенням у стандартних чи інших бібліотеках (наприклад, memcmp
, strcmp
й інші для C; Comparable#compareTo
і Comparator#compare
для Java; тощо).
Деякі з мов (чи бібліотек) однозначно регламентують результат цієї операції як число −1
, 0
чи 1
(наприклад, Perl[2]), інші дотримуються гнучкіших формулювань. Зазвичай (наприклад, у Ceylon, Groovy, PHP; у C для strcmp
-подібних функцій; у Java для Comparable#compareTo
і Comparator#compare
) специфікація чи інша документація оголошує, що результат може бути будь-яким цілим числом, знак якого має відповідати свіввідношенню операндів/аргументів (наприклад, 10 <=> 5
поверне якесь додатне число, необов'язково саме 1
, а 4 <=> 17
— якесь від'ємне число, необов'язково саме −1
). Наприклад, у PHP результатом виразу a <=> b
найчастіше виступає число −1
, 0
чи 1
, однак програміст не може покладатися на це, оскільки нема гарантій, що ця поведінка не зміниться в іншій версії чи в іншому оточенні. У C++20 результат оператора <=>
типізовано навіть не цілими числами, а іншими типами даних (std::strong_ordering
й подібні), які хоча дозволяють виконувати певні операції й надають певні гарантії, але не приводяться неявно до цілих чисел. (Загалом ця ситуація дещо нагадує ситуацію з представленням логічних значень у різних мовах: у деяких мовах значення «істина» — це строго 1
, у деяких — будь-яке ненульове число приймається за «істину», у деяких логічні значення зовсім несумісні з цілочисельним типом даних.) Деякі мови мають вбудовані засоби, що дозволяють легко «нормалізувати» результат тришляхового порівняння до множини за бажання (наприклад, методи Integer.signum
у Java й Math.sign
у C#).
У термінології деяких мов програмування (зокрема Perl) оператор тришляхового порівняння називається англ. spaceship operator — дослівно «оператор „космічний корабель“, оператор „зореліт“». Назва з'явилася, імовірно, через візуальну подібність до деяких варіантів зображень зорельотів. Рендел Шварц, відомий експерт і автор книжок з Perl, стверджує, що він особисто ввів цю назву в обіг, бо втомився казати «оператор „менше ніж, дорівнює, більше ніж“», а <=>
нагадувало йому зображення в грі «Зоряний шлях» 1971 року; утім не виключено, що одна й та сама ідея могла приходити до різних людей (дехто вважає, що назва з'явилася через подібність вигляду оператора до зорельотів «TIE Fighter» у «Зоряних війнах»).
Якщо мова програмування (чи бібліотека) допускає непорівня́нні (невпорядковні) значення (зокрема підтримує IEEE 754 з його NaN), то виникає питання, який саме результат для них повинен повертати оператор. Різні мови програмування (бібліотеки) по-різному вирішують цю проблему:
- C++20 дозволяє повертати в таких випадках значення
std::partial_ordering::unordered
, фактично перетворюючи тришляхове порівняння на чотирихляхове для деяких типів вхідних даних. - Класи
Double
іFloat
у Java, реалізуючи інтерфейсComparable
, вважають значення NaN найбільшим можливим — навіть більшим за +∞. - Деякі у випадку неможливості порівняти операнди (незалежно від того, з якого саме боку непорівня́нне значення) відповідають «більше».
- Деякі не конкретизують поведінку в такому випадку.
Обчислення на рівні апаратного забезпечення
Ця операція в входить в набори команд багатьох процесорів. Цілі числа на деяких машинах представлені у вигляді знак-і-величина або в оберненому коді (див. представлення чисел зі знаком), обидва підходи дозволяють відрізнити додатний і від'ємний нулі. Це не порушує трихотомію якщо прийнято узгоджений лінійний порядок: правильно або -0 = +0, або -0 < +0. Однак, загальновживані типи з рухомою комою мають виняток із тріхотомії: в них наявне спеціальне значення "NaN" (не число) таке, що всі вирази x < NaN, x > NaN та x = NaN хибні для всіх x з рухомою комою (включно з самим NaN).
Література
- O. Smolsky. “Defaulted comparison operators” (WG21 paper, 2014-02-19).
- B. Stroustrup. “Default Comparisons (R2)” (WG21 paper, 2015-04-09).
- B. Stroustrup. “Thoughts about Comparisons (R2)” (WG21 paper, 2015-04-09).
- O. Smolsky. “On generating default comparisons” (Kona 2015 wiki, Oct 2015).
- L. Crowl. “Comparison in C++” (WG21 paper, 2016-11-27).
- J. Maurer. “Proposed wording for default comparisons, revision 4” (WG21 paper, 2016-06-23).
- L. Crowl. “Comparison in C++: Basic Facilities” (WG21 paper, 2016-10-15).
- W. Brown. “An Extensible Approach to Obtaining Selected Operators” (WG21 paper, 2016-10-10).
- T. Van Eerd. “Bravely Default” (WG21 paper, 2016-10-15).
- D. Stone. “Implicit and Explicit Default Comparison Operators” (WG21 paper, 2016-09-18).
Зноски
- Кочерга, О.; Мейнарович, Є. (2010). Англійсько-українсько-англійський словник наукової мови (фізика та споріднені науки). Частина І англійсько-українська.
- perlop - perldoc.perl.org. perldoc.perl.org. Процитовано 5 червня 2020.