Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I perform a XOR calculation of two binary numbers in excel 2007

I wanted to perform a XOR calculation of two Binary numbers for example: on Sheet 1

Range A1 = 10101010
Range A2 = 11100010

Now I need to perform XOR of A1, A2 result in A3. I tried different formula's two perform XOR calculations like: A1^A2, (BITXOR (A1, A2)) but unfortunately it didn't worked I think because I am using excel 2007 "XOR" doesn't support.

I'm expecting a result of 1001000.

like image 502
user3520101 Avatar asked May 09 '14 18:05

user3520101


1 Answers

First, you should note that Excel pre-Excel2013 has no bitwise operators or functions built-in (Excel's OR() function is logical even if the operands are numeric). Excel 2013 finally adds this glaringly missing functionality.

Using VBA

The simplest way is to create a User Defined Function that does it. Formulae can work if you are prepared for either a decimal output, or helper columns, or a very repetitive Concatenate formula but VBA gets around these limitations - I recommend it if you are able to have code in the workbook.

Decimal Input, Decimal Output

The below examples just expose the built-in bitwise operators to use as functions in Excel formulae. I assume an integral type, although you could change it to accept decimals etc.

You can convert your string binary numbers (e.g. "1010") to decimals (10, for the previous example) using the BIN2DEC() function built-in to Excel, although this only handles 9 bits + sign bit, alternatively you can use an array formula to convert it for you (see my section on "Using Formulas" below).

Public Function BITWISE_OR(operand1, operand2)
   BITWISE_OR = CLng(operand1) Or CLng(operand2)
End Function
Public Function BITWISE_AND(operand1, operand2)
   BITWISE_AND = CLng(operand1) And CLng(operand2)
End Function
Public Function BITWISE_XOR(operand1, operand2)
   BITWISE_XOR = CLng(operand1) Xor CLng(operand2)
End Function

Converting the numeric results back to binary strings is pretty annoying with formulas - if you need more than the range covered by DEC2BIN() (a paltry -512 to +511) function built in to Excel then I would suggest either using VBA (see below), or building up your binary string bit by bit using columns or rows (see my Using Formulas section below).

Binary string input, Binary string output

The below essentially iterates through a string setting each bit in turn based on the corresponding bits in the input strings. It performs the bit changes on the string in-place using Mid$ statement. Bit strings can be arbitrary length.

The below looks complicated but really it is the same basic stuff repeated 3 times for each of And, Or and XOr.

'str1, str2: the two bit strings. They can be different lengths.
'significantDigitsAreLeft: optional parameter to dictate how different length strings should be padded. Default = True.
Public Function Bitstr_AND(str1 As String, str2 As String, Optional significantDigitsAreLeft As Boolean = True)
    Dim maxLen As Long, resStr As String, i As Long
    If Len(str1) > Len(str2) Then maxLen = Len(str1) Else maxLen = Len(str2) 'get max length of the two strings
    str1 = getPaddedString(str1, maxLen, significantDigitsAreLeft) 'pad left or right to the desired length
    str2 = getPaddedString(str2, maxLen, significantDigitsAreLeft) 'pad left or right to the desired length
    resStr = String$(maxLen, "0") 'prepare the result string into memory (Mid$ can operate without creating a new string, for performance)
    For i = 1 To maxLen
        If Mid$(str1, i, 1) = "1" And Mid$(str2, i, 1) = "1" Then
            Mid$(resStr, i, 1) = "1" 'in-place overwrite of the existing "0" with "1"
        End If
    Next i
    Bitstr_AND = resStr
End Function
'For explanatory comments, see Bitstr_AND
Public Function Bitstr_OR(str1 As String, str2 As String, Optional significantDigitsAreLeft As Boolean = True)
    Dim maxLen As Long
    Dim resStr As String
    Dim i As Long
    If Len(str1) > Len(str2) Then maxLen = Len(str1) Else maxLen = Len(str2)
    str1 = getPaddedString(str1, maxLen, significantDigitsAreLeft)
    str2 = getPaddedString(str2, maxLen, significantDigitsAreLeft)
    resStr = String$(maxLen, "0")
    For i = 1 To maxLen
        If Mid$(str1, i, 1) = "1" Or Mid$(str2, i, 1) = "1" Then
            Mid$(resStr, i, 1) = "1"
        End If
    Next i
    Bitstr_OR = resStr
End Function
'For explanatory comments, see Bitstr_AND
Public Function Bitstr_XOR(str1 As String, str2 As String, Optional significantDigitsAreLeft As Boolean = True)
    Dim maxLen As Long
    Dim resStr As String
    Dim i As Long
    If Len(str1) > Len(str2) Then maxLen = Len(str1) Else maxLen = Len(str2)
    str1 = getPaddedString(str1, maxLen, significantDigitsAreLeft)
    str2 = getPaddedString(str2, maxLen, significantDigitsAreLeft)
    resStr = String$(maxLen, "0")
    For i = 1 To maxLen
        If Mid$(str1, i, 1) = "1" Then
            If Not Mid$(str2, i, 1) = "1" Then
                Mid$(resStr, i, 1) = "1"
            End If
        ElseIf Mid$(str2, i, 1) = "1" Then 'Save an If check by assuming input string contains only "0" or "1"
            Mid$(resStr, i, 1) = "1"
        End If
    Next i
    Bitstr_XOR = resStr
End Function
'Helper to pad string
Private Function getPaddedString(str As String, length As Long, padLeft As Boolean) As String
    If Len(str) < length Then
        If padLeft Then
            getPaddedString = String$(length - Len(str), "0") & str
        Else
            getPaddedString = str & String$(length - Len(str), "0")
        End If
    Else
        getPaddedString = str
    End If
End Function

Using Formulas

You can do an XOR operation using Text functions or Sumproduct. This may be more appropriate if you do not want to use VBA but formulas are painful to ensure they covers all situations, like negatives or different length binary strings. I refer you to the superb blog post http://www.excelhero.com/blog/2010/01/5-and-3-is-1.html for examples using Sumproduct, and http://chandoo.org/wp/2011/07/29/bitwise-operations-in-excel/ for examples using Text functions.

I cooked up my own formulae that handles certain cases and I explain them below to guide you.

Binary string Input, Decimal Output

In the below, A2 and B2 refer to the two binary numbers in up to 32-bits string form. The strings can be variable length, as the formula will pad with 0's to the necessary length. It should be obvious how to increase it to more bits. They must be entered using Ctrl+Shift+Enter.

The most significant bit is on the left. To make it least significant bit on the left, you can remove the little subtraction in the powers of 2 part, and make it pad to the right.

Bitwise And:

=SUM((((MID(REPT("0",32-LEN($A$2))&$A$2,ROW($1:$32),1)="1")+(MID(REPT("0",32-LEN($B$2))&$B$2,ROW($1:$32),1)="1"))=2)*(2^(32-ROW($1:$32))))

Bitwise Or:

=SUM((((MID(REPT("0",32-LEN($A$2))&$A$2,ROW($1:$32),1)="1")+(MID(REPT("0",32-LEN($B$2))&$B$2,ROW($1:$32),1)="1"))>0)*(2^(32-ROW($1:$32))))

Bitwise Xor:

=SUM((((MID(REPT("0",32-LEN($A$2))&$A$2,ROW($1:$32),1)="1")+(MID(REPT("0",32-LEN($B$2))&$B$2,ROW($1:$32),1)="1"))=1)*(2^(32-ROW($1:$32))))

Binary string input, Binary string Output

A single cell solution would be arduous because there is no array concatenation formula in Excel. You could do it using the CONCATENATE function glueing together each bits, with each bit being the result of an If comparing each binary string returning 1 or 0 as appropriate. As I said, though easy (just build it up like =IF(Mid(A1,1,1) = "1",...), this would be boring so I personally won't do it for you ;)

Alternatively, you could do it more simply using columns or rows to build up the string, like: If A1 and B1 have your binary strings, then in C1 put (for AND, or for OR change the =2 at the end to >0 and for XOR change it to =1):

=IF((MID($A1,1,1)="1")+(MID($B1,1,1)="1"))=2,"1","0")

Then in D1 put:

=C1 & IF((MID($A1,COLUMN()-COLUMN($C1),1)="1")+(MID($B1,COLUMN()-COLUMN($C1),1)="1"))=2,"1","0")

Then drag this across as many columns as bits

like image 109
Cor_Blimey Avatar answered Oct 03 '22 22:10

Cor_Blimey