المشغلين المنطقيين مقابل مشغلات bitwise
-
27-09-2019 - |
سؤال
أنا في حيرة من أمري مع متى يجب أن أستخدم مشغلي 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
تعال مباشرة من المنطق المنطقي (وبالتالي تعمل على اثنين من المنطقية لإنتاج منطقية) ، بينما &
و |
تطبيق منطقية و/أو على أجزاء من الأعداد الصحيحة الفردية. هناك الكثير من الأسئلة هنا حول كيفية عمل الأخير بالضبط.
فيما يلي اختلافات عملية يمكن أن تؤثر على نتائجك:
and
وor
دائرة قصيرة ، أيTrue or sys.exit(1)
لن يخرج ، لأنه بالنسبة لقيمة معينة (True or ...
,False and ...
) من المعامل الأول ، فإن الثاني لن يغير النتيجة = لا يلزم تقييمها. لكن|
و&
لا تقصر الدائرة -True | sys.exit(1)
يلقي لك outta repl.- (ينطبق فقط على بعض اللغات مع زيادة التحميل ، بما في ذلك Python :)
&
و|
هم مشغولون منتظمون ويمكن أن يكونوا محمولين -and
وor
يتم تزويدها في اللغة (على الرغم من على الأقل في بيثون ، فإن الطريقة الخاصة للإكراه على منطقية قد يكون لها آثار جانبية). - (ينطبق فقط على بضع لغات [انظر تعليق 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