سؤال
حسنًا، لدي خليتين تحتويان على سلسلة من البتات 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