سؤال

أنا في حيرة من أمري مع متى يجب أن أستخدم مشغلي Boolean vs Bitwise

  • and ضد &
  • or ضد |

هل يمكن لشخص ما أن ينيرني عندما أستخدم كل منهما ومتى سيؤثر استخدام واحد على الآخر على نتائجي؟

هل كانت مفيدة؟

المحلول

فيما يلي بعض الإرشادات:

  • عادة ما يتم استخدام مشغلي منطقية منطقية القيم ولكن عادة ما يتم استخدام مشغلي bitwise عدد صحيح القيم.
  • مشغلي منطقية دائرة قصيرة لكن مشغلي bitwise هم ليس دائرة قصيرة.

سلوك الدائرة القصيرة مفيد في التعبيرات مثل هذا:

if x is not None and x.foo == 42:
    # ...

هذا لن يعمل بشكل صحيح مع bitwise & المشغل لأنه سيتم تقييم الجانبين دائمًا ، مع العطاء AttributeError: 'NoneType' object has no attribute 'foo'. عندما تستخدم المنطق andالمشغل لا يتم تقييم التعبير الثاني عندما يكون الأول خطأ. بصورة مماثلة or لا يقيم الحجة الثانية إذا كان الأول صحيحًا.

نصائح أخرى

نظريا، and و or تعال مباشرة من المنطق المنطقي (وبالتالي تعمل على اثنين من المنطقية لإنتاج منطقية) ، بينما & و | تطبيق منطقية و/أو على أجزاء من الأعداد الصحيحة الفردية. هناك الكثير من الأسئلة هنا حول كيفية عمل الأخير بالضبط.

فيما يلي اختلافات عملية يمكن أن تؤثر على نتائجك:

  1. and و or دائرة قصيرة ، أي True or sys.exit(1) لن يخرج ، لأنه بالنسبة لقيمة معينة (True or ..., False and ...) من المعامل الأول ، فإن الثاني لن يغير النتيجة = لا يلزم تقييمها. لكن | و & لا تقصر الدائرة - True | sys.exit(1) يلقي لك outta repl.
  2. (ينطبق فقط على بعض اللغات مع زيادة التحميل ، بما في ذلك Python :) & و | هم مشغولون منتظمون ويمكن أن يكونوا محمولين - and و or يتم تزويدها في اللغة (على الرغم من على الأقل في بيثون ، فإن الطريقة الخاصة للإكراه على منطقية قد يكون لها آثار جانبية).
  3. (ينطبق فقط على بضع لغات [انظر تعليق Kennytm] :) and و or العودة (دائمًا؟ لا تفهم هذا حقًا ، ولا أحتاجه) قيمة المعامل بدلاً من True أو False. هذا لا يغير معنى التعبيرات المنطقية في الظروف - 1 or True هو 1, ، لكن 1 صحيح أيضًا. لكنه كان يستخدم ذات مرة لمحاكاة مشغل مشروط (cond ? true_val : false_val في بناء الجملة ، true_val if cond else false_val في بيثون منذ بضع سنوات). ل & و |, يعتمد نوع النتيجة على كيفية تحميل المعاملات للطرق الخاصة المعنية (True & False هو False, 99 & 7 هو 3, ، بالنسبة للمجموعات ، فهي النقابات/التقاطع ...).

ولكن حتى عندما على سبيل المثال a_boolean & another_boolean هل يعمل بشكل متماثل ، الحل الصحيح هو استخدام and - ببساطة لأن and و or ترتبط بالتعبير والشرط المنطقي أثناء & و | قف ل bit twiddling.

إليك فرق إضافي ، الأمر الذي جعلني أشعر بالحيرة لفترة من الوقت الآن: لأن & (وغيرهم من المشغلين الشهين) لها أسبقية أعلى من and (وغيرهم من المشغلين المنطقيين) تقوم التعبيرات التالية بتقييم قيم مختلفة:

0 < 1 & 0 < 2

مقابل

0 < 1 and 0 < 2

لذكاء ، أول عوائد False لأنه يعادل 0 < (1 & 0) < 2, ، بالتالي 0 < 0 < 2, ، بالتالي 0 < 0 and 0 < 2.

إذا كنت تحاول القيام بعمليات منطقية من العناصر في numpy, ، الجواب مختلف إلى حد ما. يمكنك استخدام & و | للعمليات المنطقية العناصر ، ولكن and و or سيعود خطأ القيمة.

لتكون على الجانب الآمن ، يمكنك استخدام وظائف المنطق numpy.

np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False,  True], dtype=bool)

np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False,  True], dtype=bool)

العمليات المنطقية هي عمليات منطقية.

عمليات bitwise هي عمليات على البتات الثنائية.

عمليات bitwise:

>>> k = 1
>>> z = 3
>>> k & z  
1
>>> k | z  
3

العمليات:

And & 1 if both bits are 1, 0 otherwise
Or  | 1 if either bit is 1
Xor ^ 1 if the bits are different, 0 if they're the same
Not ~ Flip each bit

بعض استخدامات عمليات bitwise:

1) إعداد البتات ومسحها

العمليات المنطقية:

>>> k = True
>>> z = False
>>> k & z  # and
False
>>> k | z  # or
True
>>> 

التلميح في الاسم:

  • مشغلي منطقية للأداء العمليات المنطقية (اختبار الحقيقة شائع في البرمجة والمنطق الرسمي)
  • مشغلو bitwise هم "بتات بت" (معالجة منخفضة المستوى من البتات في أنواع البايت والبيانات الرقمية)

على الرغم من أنه من الممكن وفي بعض الأحيان مرغوبًا في بعض الأحيان (عادةً لأسباب كفاءة) لإجراء عمليات منطقية مع مشغلي bitwise ، يجب أن تتجنبها عمومًا لمثل هذه الأغراض لمنع الحشرات الدقيقة والآثار الجانبية غير المرغوب فيها.

إذا كنت بحاجة إلى معالجة البتات ، فسيتم تصميم مشغلي bitwise غرضًا. كتاب المرح: فرحة المتسللين يحتوي على بعض الأمثلة الباردة والمفيدة حقًا لما يمكن تحقيقه مع البت.

القاعدة العامة هي استخدام المشغل المناسب للمعاملات الحالية. استخدم مشغلي Boolean (المنطقي) مع المعاملات المنطقية ، ومشغلي bitwise مع معاملات متكاملة (أوسع) (ملاحظة: خطأ شنيع يعادل 0, ، و حقيقي ل 1). السيناريو "الصعب" الوحيد هو تطبيق المشغلين المنطقيين على المعاملات غير المنطقية.
لنأخذ مثالًا بسيطًا ، كما هو موضح في SO]: Python - الاختلافات بين "و" و "و" [مكررة: 5 & 7 ضد. 5 and 7.

ل bitwise و (&) ، الأمور واضحة جدا:

5     = 0b101
7     = 0b111
-----------------
5 & 7 = 0b101 = 5

ل منطقي و, ، هذا ماذا بيثون 3]: العمليات المنطقية تنص على (تشديد هو لي):

(لاحظ أنه لا و ولا أو تقييد القيمة والنوع الذي يعودون إليه خطأ شنيع و حقيقي, ، لكن بالأحرى إرجاع الحجة الأخيرة التي تم تقييمها.

مثال:

>>> 5 and 7
7
>>> 7 and 5
5

بالطبع ، ينطبق الشيء نفسه | ضد. أو.

Boolean "و" vs. bitwise '&':

ساعدني Pseudo-Code/Python على فهم الفرق بين هذه:

def boolAnd(A, B):
    # boolean 'and' returns either A or B
    if A == False:
        return A
    else:
        return B

def bitwiseAnd(A , B):
    # binary representation (e.g. 9 is '1001', 1 is '0001', etc.)

    binA = binary(A)
    binB = binary(B)



    # perform boolean 'and' on each pair of binaries in (A, B)
    # then return the result:
    # equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])

    # assuming binA and binB are the same length
    result = []
    for i in range(len(binA)):
      compar = boolAnd(binA[i], binB[i]) 
      result.append(compar)

    # we want to return a string of 1s and 0s, not a list

    return ''.join(result)

العمليات المنطقية

عادة ما تستخدم للبيانات الشرطية. علي سبيل المثال:

if a==2 and b >10 then /*Do something...*/ endif وهذا يعني ما إذا كان كلتا الحالتين ((A == 2) (B> 10)) صحيحة في نفس الوقت ، ثم يمكن تنفيذ هيئة البيان الشرطي.

عمليات bitwise

يمكن استخدام عمليات bitwise لمعالجة البيانات واستخراجها. على سبيل المثال ، إذا كنت ترغب في استخراج أربعة LSB (الأقل أهمية) من عدد صحيح ، يمكنك القيام بذلك:

اِستِخلاص:

poo & 0x000F

قناع:

poo | 0xFFF0

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top