سؤال

حسنًا، لدي خليتين تحتويان على سلسلة من البتات 0111010 و0101011.أريد XOR الاثنين معًا بحيث تكون الخلية الناتجة 0010001.

أعلم أنه يمكنك استخدام هذا للقيم المنطقية

=OR(AND(A1,NOT(A2)),AND(A2,NOT(A1)))

لكنها لا تعمل مع سلسلة من البتات.

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

المحلول

وتحتاج إلى استخدام VBA للقيام بذلك. إذا قمت بفتح VBA، إنشاء وحدة نمطية جديدة وإدخال الدالة

Public Function BITXOR(x As Long, y As Long)
    BITXOR = x Xor y
End Function

ويمكنك بعد ذلك استخدام DEC2BIN وBIN2DEC لتحويل من ثنائي إلى عشري لتشغيل هذه الوظيفة. على سبيل المثال:

والخلية A1 = 0111010

والخلية A2 = 0101011

=DEC2BIN(BITXOR(BIN2DEC(A1),BIN2DEC(A2)))

نصائح أخرى

ويمكنك القيام بذلك مع VBA:

Public Function XOR_binary(b1, b2) As String
    Dim len_b1
    Dim len_b2
    Dim len_diff
    Dim i
    Dim bit1
    Dim bit2

    ' see if the two string are the same length. If not, add 0's to
    ' the beginning of the shorter string

    len_b1 = Len(b1)
    len_b2 = Len(b2)
    len_diff = len_b1 - len_b2

    Select Case len_diff
        Case Is < 0
            ' b2 is longer
            b1 = String(Abs(len_diff), "0") & b1
        Case Is = 0
            ' they're the same length
        Case Is > 0
            ' b1 is longer
            b2 = String(len_diff, "0") & b2
    End Select

    XOR_binary = ""

    For i = Len(b2) To 1 Step -1
        bit1 = CInt(Mid(b1, i, 1))
        bit2 = CInt(Mid(b2, i, 1))

        XOR_binary = CInt(bit1 Xor bit2) & XOR_binary
    Next i

End Function

وربما لا يكون أفضل تنفيذ، لكنه يعمل.

وعن طريق المثال الخاص بك، A3 يحتوي على:

=XOR_Binary(A1,A2)

والسلسلة الناتجة سيكون لها نفس عدد البتات كما أطول سلسلة قمت بتمرير في.

هنا هو الحل بدون استخدام VBA:
=TEXT(SUMPRODUCT(MOD(INT(MID(A1,{1,2,3,4,5,6,7},1))+INT(MID(A2,{1,2,3,4,5,6,7},1)),2),{1000000,100000,10000,1000,100,10,1}),"0000000")

هذا يحسب bitwise XOR استخدام SUMPRODUCT و TEXT لتحويلها إلى سلسلة من البتات.

ملحوظة: تتطلب هذه الصيغة أن يكون طول قيمتي الإدخال 7 (حسب المثال الخاص بك) وسيكون طول الإخراج أيضًا 7.للسماح بأطوال إدخال مختلفة، ما عليك سوى تنفيذ الاقتطاع و/أو الحشو اللازم.


يمكنك اختيار استخدام بعض التعريفات المختصرة:

  • يُعرِّف BitPositions مثل ={1,2,3,4,5,6,7} (7 بت)،
  • يُعرِّف BitStrings مثل ={1000000,100000,10000,1000,100,10,1} (7 بت)،
  • يُعرِّف BitFormat مثل ="0000000" (7 بت)،

بعد ذلك يمكن جعل الصيغة الخاصة بك أكثر وضوحًا/أقصر/أنظف:
=TEXT(SUMPRODUCT(MOD(INT(MID(A1,BitPositions,1))+INT(MID(A2,BitPositions,1)),2),BitStrings),BitFormat)

وهذا أيضًا يسهل العمل مع سلاسل أكبر من البتات، على سبيل المثال:

  • يُعرِّف BitPositions مثل =ROW(INDIRECT("1:32")) (32 بت)،
  • يُعرِّف BitStrings مثل =10^(32-ROW(INDIRECT("1:32"))) (32 بت)،
  • يُعرِّف BitFormat مثل =REPT("0",32) (32 بت)

إذا كنت ترغب في التنفيذ NOT/OR/AND/إلخ.ثم يمكنك الحصول على الإلهام الخاص بك من هذه الصيغ للنظائر العشرية;هنا بعض التفسيرات أكثر تعمقا ل XOR مع SUMPRODUCT على الرغم من أنه يستخدم أيضًا المدخلات العشرية.

و= 1- (A1 <> 0) + (A2 <> 0) لكل قليلا.

ويمكنك تقسيمه إلى الأعمدة الفردية للصيغة المذكورة أعلاه باستخدام هذا: = MID (A1 | 7 | 1) = MID (A1 | 6 | 1) = MID (A1 | 5 | 1) = MID (A1 | 4 | 1) = MID (A1 | 3 | 1) = MID (A1 | 2 | 1) = MID (A1 | 1 | 1) ...

'هذا VBA إرجاع ضعف هذا لابد من تنسيق في ورقة العمل.

Option Explicit
Public Function MYXOR(r1 As Range, r2 As Range) As Double
'r1 and r2 are expected as HEX; for example, 
'DEC2HEX(CODE("B")) returns ASCII of "B" as HEX
On Error GoTo ErrHandler
  MYXOR = "&H" & r1.Value Xor "&H" & r2.Value
  GoTo CleanUp
ErrHandler:
  MYXOR = Err.Number
  Resume CleanUp
CleanUp:
' format the double being returned in MYXOR with TEXT(DEC2HEX(MYXOR(C9,F9)),"00000")
' number of leading zeroes according to the size of the HEX in r1 and r2
End Function
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top