مقارنة ثلاثية

في علوم الحاسوب ، تأخذ المقارنة الثلاثية قيمتين A و B تنتميان إلى نوع ذي ترتيب كلي وتحدد ما إذا كانت A < B أو A = B أو A > B في عملية واحدة، وفقًا للقانون الرياضي للتقسيم الثلاثي .

يمكن تنفيذه من حيث دالة ( كما هو الحال strcmpفي لغة C )، أو طريقة (كما هو الحال compareToفي لغة Java )، أو عامل تشغيل (مثل عامل تشغيل المركبة الفضائية<=> في لغات Perl و PHP و C++ ).

الحوسبة على مستوى الآلة

تحتوي معظم المعالجات على مجموعات تعليمات تدعم هذه العملية على الأنواع الأولية. في بعض الأجهزة، تقوم تعليمات المقارنة بتعيين علامات [ أ ] يمكن اختبارها بواسطة تعليمات التفرع الشرطي اللاحقة. [ ب ]

في بعض الأجهزة التي تعتمد على معالجة الكلمات، تكون تعليمات المقارنة عبارة عن تخطي ، حيث تستمر العملية عند عداد البرنامج (PC) أو عداد البرنامج + 1 أو عداد البرنامج + 2، وذلك حسب نتيجة المقارنة. [ ج ] تحتوي معظم هذه الأجهزة أيضًا على تعليمات تفرع شرطية.

تعتمد بعض الآلات في تمثيل الأعداد الصحيحة الموقعة على تمثيل الإشارة والمقدار أو تمثيل المتمم الأحادي (انظر تمثيلات الأعداد الموقعة )، وكلاهما يسمح بوجود صفر موجب وصفر سالب . لا يُخالف هذا مبدأ الثلاثية طالما تم اعتماد ترتيب كلي ثابت: إما أن يكون −0 = +0 أو −0 < +0 صحيحًا. مع ذلك، تُستثنى أنواع الأعداد العشرية الشائعة من مبدأ الثلاثية: توجد قيمة خاصة "NaN" ( ليست عددًا ) بحيث تكون العبارات x < NaN و x > NaN و x = NaN خاطئة لجميع قيم الأعداد العشرية x (بما في ذلك NaN نفسها).

لغات البرمجة عالية المستوى

القدرات

في لغة C ، تُجري الدالتان `int` strcmpو`int` memcmpمقارنة ثلاثية بين السلاسل النصية ومخازن الذاكرة، على التوالي. تُرجعان قيمة سالبة عندما يكون الوسيط الأول أصغر معجميًا من الوسيط الثاني، وصفرًا عندما يكون الوسيطان متساويين، وقيمة موجبة في غير ذلك. يُعمم هذا الاصطلاح، المتمثل في إرجاع "إشارة الفرق"، ليشمل دوال المقارنة المختلفة بواسطة دالة الفرز القياسية `sorting` qsort، التي تأخذ دالة مقارنة كوسيط وتشترط عليها الالتزام بهذا الاصطلاح.

في لغات البرمجة بيرل (للمقارنات العددية فقط، cmpويُستخدم المعامل للمقارنات المعجمية للسلاسل النصية)، وبي إتش بي (منذ الإصدار 7)، وروبي ، وأباتشي جروفي ، يُعيد معامل "المركبة الفضائية" <=>القيم -1، 0، أو 1، وذلك بحسب ما إذا كان A < B، أو A = B، أو A > B، على التوالي. وتقوم دوال بايثون 2.x cmp(التي أُزيلت في الإصدار 3.x)، و OCamlcompare ، وكوتلنcompareTo بحساب الشيء نفسه. وفي مكتبة هاسكل القياسية ، تُعرَّف دالة المقارنة الثلاثية لجميع الأنواع في الفئة ؛ وهي تُعيد النوع ، الذي تكون قيمه (أصغر من)، (يساوي)، و (أكبر من): [ 3 ]compareOrdOrderingLTEQGT

ترتيب البيانات = أقل | يساوي | أكبر

تحتوي العديد من لغات البرمجة كائنية التوجه على دالة مقارنة ثلاثية ، تُجري مقارنة ثلاثية بين كائنين مُحددين. على سبيل المثال، في لغة جافا ، أي فئة تُنفذ Comparableواجهة `int` تحتوي على compareToدالة تُرجع إما عددًا صحيحًا سالبًا، أو صفرًا، أو عددًا صحيحًا موجبًا، أو تُطلق استثناءً NullPointerException(إذا كان أحد الكائنين أو كلاهما `int` null). وبالمثل، في إطار عمل .NET ، أي فئة تُنفذ IComparableواجهة `int` تحتوي على دالة مماثلة CompareTo. في لغة C++ ، أي فئة قابلة للمقارنة الثلاثية يمكن أن تكون مُعاملًا لنسخ منstd::compare_three_way `int` ، أو `int` std::strong_order، std::weak_orderأو `int`، أو std::partial_order`int`.

منذ إصدار جافا 1.5، يُمكن حساب نفس النتيجة باستخدام Math.signumالدالة الثابتة إذا أمكن معرفة الفرق دون مشاكل حسابية مثل تجاوز السعة الحسابية المذكور أدناه. تسمح العديد من لغات البرمجة بتعريف الدوال، لذا يُمكن تصميم دالة compare(A,B) بشكل مناسب، ولكن السؤال هو ما إذا كان تعريفها الداخلي يُمكن أن يستخدم صيغة ثلاثية الاتجاه أم أنه يجب الاعتماد على اختبارات متكررة.

عند تطبيق مقارنة ثلاثية حيث لا يتوفر عامل أو طريقة مقارنة ثلاثية، فمن الشائع دمج مقارنتين، مثل A = B و A < B، أو A < B و A > B. من حيث المبدأ، قد يستنتج المترجم أنه يمكن استبدال هذين التعبيرين بمقارنة واحدة فقط متبوعة باختبارات متعددة للنتيجة، ولكن لا يوجد ذكر لهذا التحسين في النصوص المتعلقة بهذا الموضوع.

في بعض الحالات، يمكن محاكاة المقارنة الثلاثية بطرح A وB وفحص إشارة الناتج، وذلك باستخدام تعليمات خاصة لفحص إشارة العدد. مع ذلك، يتطلب هذا أن يكون لنوع A وB فرق محدد جيدًا. قد يحدث تجاوز في الأعداد الصحيحة الموقعة ذات العرض الثابت عند طرحها، بينما تأخذ الأعداد العشرية القيمة NaN بإشارة غير محددة، ولا تحتوي السلاسل النصية على دالة فرق تُطابق ترتيبها الكلي. على مستوى الآلة، عادةً ما يتم تتبع التجاوز ويمكن استخدامه لتحديد الترتيب بعد الطرح، لكن هذه المعلومات عادةً ما تكون غير متاحة للغات البرمجة عالية المستوى.

في إحدى حالات الشرط الثلاثي الذي توفره لغة البرمجة، تأخذ عبارة IF الحسابية الثلاثية التي تم إيقاف استخدامها في لغة فورتران في الاعتبار إشارة التعبير الحسابي وتقدم ثلاثة تسميات للانتقال إليها وفقًا لإشارة النتيجة:

إذا كانت ( التعبير ) سالبة ، صفر ، موجبة

تُعد دالة المكتبة الشائعة strcmp في لغة C واللغات ذات الصلة مقارنة معجمية ثلاثية للسلاسل النصية؛ ومع ذلك، تفتقر هذه اللغات إلى مقارنة ثلاثية عامة لأنواع البيانات الأخرى.

مشغل سفن فضائية

يُشار إلى عامل المقارنة الثلاثي أو "عامل المركبة الفضائية" للأرقام كما هو موضح <=>في لغات البرمجة Perl و Ruby و Apache Groovy و PHP و Eclipse Ceylon و C++ . [ 4 ]

في لغة C++ ، أضافت مراجعة C++20 عامل المقارنة "spaceship" <=>، الذي يُرجع قيمة تُحدد ما إذا كانت القيمتان متساويتين، أو أصغر، أو أكبر، أو غير مرتبة، ويمكن أن يُرجع أنواعًا مختلفة اعتمادًا على مدى دقة المقارنة. [ 5 ]

يعود أصل الاسم إلى تذكير راندال إل. شوارتز بسفينة الفضاء في لعبة ستار تريك المكتوبة بلغة HP BASIC . [ 6 ] وقد اقترح مبرمج آخر أن التسمية جاءت لتشابهها مع مقاتلة دارث فيدر من طراز TIE في سلسلة أفلام حرب النجوم . [ 7 ]

مثال بلغة PHP:

صدى 1 <=> 1 ; // 0 صدى 1 <=> 2 ; // -1 صدى 2 <=> 1 ; // 1

مثال بلغة C++:

1 <=> 1 ; // تُقيّم إلى std::strong_ordering::equal 1 <=> 2 ; // تُقيّم إلى std::strong_ordering::less 2 <=> 1 ; // تُقيّم إلى std::strong_ordering::greater

أنواع البيانات المركبة

تتميز المقارنات الثلاثية بسهولة تكوينها وبناء مقارنات معجمية لأنواع البيانات غير الأولية، على عكس المقارنات الثنائية.

إليك مثال على التركيب في لغة بيرل.

دالة المقارنة الفرعية ($$) { my ( $a , $b ) = @_ ; return $a -> { unit } cmp $b -> { unit } || $a -> { rank } <=> $b -> { rank } || $a -> { name } cmp $b -> { name }; }

لاحظ أن cmp`_____` في لغة بيرل تُستخدم للسلاسل النصية، بينما <=>تُستخدم `______` للأرقام. عادةً ما تكون الصيغ الثنائية المكافئة أقل اختصارًا، ولكن ليس بالضرورة أقل وضوحًا. تستفيد الصيغة أعلاه من التقييم المختصر للمعامل ` ||_____`، ومن حقيقة أن الصفر يُعتبر قيمة خاطئة في بيرل. ونتيجةً لذلك، إذا كانت المقارنة الأولى متساوية (وبالتالي تُقيّم إلى صفر)، فسيتم الانتقال إلى المقارنة الثانية، وهكذا، حتى يتم العثور على قيمة غير صفرية، أو حتى الوصول إلى النهاية.

في بعض اللغات، بما في ذلك بايثون ، وروبي ، وهاسكل ، وما إلى ذلك، تتم مقارنة القوائم بشكل معجمي، مما يعني أنه من الممكن بناء سلسلة من المقارنات مثل المثال أعلاه عن طريق وضع القيم في قوائم بالترتيب المطلوب؛ على سبيل المثال، في روبي:

[ أ . الوحدة ، أ . الرتبة ، أ . الاسم ] <=> [ ب . الوحدة ، ب . الرتبة ، ب . الاسم ]

في لغة C++:

std :: tie ( a.unit , a.rank , a.name ) <=> std :: tie ( b.unit , b.rank , b.name )

عامل الربط في لغة SQL

في بعض لهجات لغة SQL ، <=>يُستخدم كعامل ربط آمن من القيم الفارغة، والذي سيطابق المعاملات إذا كانت كلتاهما فارغة. [ 8 ]

انظر أيضاً

ملحوظات

  1. تختلف المصطلحات المستخدمة في الآلات المختلفة؛ ومن المصطلحات الشائعة رمز الحالة ، والعلم ، والمؤشر ، والحالة.
  2. على سبيل المثال، قارن مع A (CMPA)، قارن مع Q (CMPQ)، قارن مع AQ (CMPAQ)، قارن مع X n (CMPXn)، قارن مع الحدود (CWL)، قارن المقدار (CMG)، على GE 635 [ 1 ]
  3. ↑ مثال : قارن بين المُراكم والتخزين (CAS) وقارن بين المُراكم المنطقي والتخزين (LAS) على جهاز IBM 7094. [ 2 ]

مراجع

  1. "مقارنة - قارن" (ملف PDF) . دليل برمجة GE-635 المرجعي (ملف PDF) . الأجهزة المتوافقة/600. GE . يوليو 1964. الصفحات II-83 – II-88 . CPB-1004 . تم الاطلاع عليه في 6 أبريل 2025 . 
  2. "تعليمات التحكم" (ملف PDF) . مبادئ تشغيل IBM 7094 (ملف PDF) . مكتبة مراجع الأنظمة. صفحة 53. A22-6703-4 . تاريخ الاسترجاع: 22 سبتمبر 2025 . 
  3. Data.Ord
  4. "Math::Complex" . وثائق برمجة بيرل . تم الاطلاع عليه بتاريخ 26 سبتمبر 2014 .
  5. اقترح هيرب ساتر إضافة عامل مقارنة ثلاثي إلى معيار لغة C++ باستخدامالصيغة المذكورة، وذلك في ورقة بحثية بعنوان "المقارنة المتسقة". انظر "المقارنة المتسقة" . وقد تم دمج هذا الاقتراح بنجاح في مسودة C++20 في نوفمبر 2017.<=>
  6. "تاريخ المركبة الفضائية (كان ردًا على: [ dart-misc ] ملاحظات اجتماع DEP)" .
  7. "مشغل المركبة الفضائية الخارقة" . 2000-12-08 . تم الاطلاع عليه بتاريخ 2014-08-06 .
  8. https://dev.mysql.com/doc/refman/8.4/en/comparison-operators.html#operator_equal-to