Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

bit operations

Status
Not open for further replies.

Bong

Programmer
Dec 22, 1999
2,063
US
I am trying to implement a CRC16 function in order to test some software. VBA might not be the best language for this but it would be convenient to have the function right there in Excel. Anyway I have the spec for the CRC computation and I have my input string (hex) converted to a collection of 16-bit integers just fine. I'm at the part of the spec where I have to
...check each bit in Temp one at a time, starting with the left-most bit. For each Temp bit equal to 1, perform the following...
Now, in other languages I have worked with, I would use a shift operator and have access to the bits that way. I looked through the help files but I couldn't find a corresponding VBA function or operator.

Can someone help me get at the bits of an integer?

_________________
Bob Rashkin
 
you may try something like this:
For i = 15 To 0 Step -1
If (Temp And 2^i) <> 0 Then
' perform the following
End If
Next

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ181-2886
 

And/Or/Xor are the operators to use but this kind of thing can be very tricky to get right in VBA.

PHV's code will not test bits left to right - for example an integer variable with a value of 128 is held as x'1000' in little endian format. Anding it with 128 will tell you that the leftmost bit is set.

A couple of questions - feel free to ignore me if you're confident you know what you're doing :) -

How have you obtained your hex input string?
How have you converted your hex input string to 16-bit numbers?

Enjoy,
Tony

--------------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.
Excel VBA Training and more Help at VBAExpress[
 
Fair questions, Tony.
Here's what I have so far:
Code:
Function crc16(hstr1)
    'convert hstr1 to collection of 16-bit integers
    Dim hlist As New Collection
    Dim LU As New Collection
    Dim chksum, tmpsum As Integer
    a = Len(hstr1)
    nelm = a / 4
    If (a Mod 4 > 0) Then
        MsgBox ("must be integer multiple of 16Bits")
        Exit Function
    End If
    For i = 1 To nelm
        st1 = "&h" & Left(hstr1, 4)
        hlist.Add (CInt(st1))
        a = a - 4
        hstr1 = Right(hstr1, a)
    Next
    'build lookup table
    LU.Add (CInt(&HA001))
    LU.Add (CInt(&HF001))
    LU.Add (CInt(&HD801))
    LU.Add (CInt(&HCC01))
    LU.Add (CInt(&HC601))
    LU.Add (CInt(&HC301))
    LU.Add (CInt(&HC181))
    LU.Add (CInt(&HC0C1))
    LU.Add (CInt(&HC061))
    LU.Add (CInt(&HC031))
    LU.Add (CInt(&HC019))
    LU.Add (CInt(&HC00D))
    LU.Add (CInt(&HC007))
    LU.Add (CInt(&HC002))
    LU.Add (CInt(&H6001))
    LU.Add (CInt(&H9001))
    'initialize
    chksum = 0
    tmpsum = hlist.Item(1) Xor chksum
    [red]'bit operations here[/red]
    'loop through hstr1 members
    'return
    crc16 = chksum
End Function

For now, I'm passing the HEX string in as an argument. When I have the function working properly, I'll condition the string on the EXCEL side, I think.

Rather than try to get the ANDing right, I was thinking of keeping the HEX string characters in an array and having another 16-member array that knows that a=1010 for instance. I was hoping for a more direct access to the bits

_________________
Bob Rashkin
 
OK. In the absence of a good bit operation set, here's what I wound up doing:
Code:
cnvarr = Array("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111")
and then
Code:
    chksum = 0
    tmpsum = hlist.Item(1) Xor chksum
    hextmp = Hex(tmpsum)
    tln = Len(hextmp)
    hextmp = String(4 - tln, "0") & hextmp
    For i = 1 To 4
        cref = Mid(hextmp, i, 1)
        cix = CInt("&H" & cref)
        btmp = cnvarr(cix)
        For j = 1 To 4
            bref = Mid(btmp, j, 1)
            If bref = "1" Then
                tblix = i * 4 + j
                chksum = chksum Xor LU.Item(tblix)
            End If
        Next
    Next

It seems awkward but I couldn't think of a better way (given my reluctance to try to develop a "mask" for ANDing. Does anyone have any suggestions?

_________________
Bob Rashkin
 
Hi Bob,

Xor works like And in terms of the bits it operates on, so I'm not sure what you are gaining by working one way as opposed to another.

My questions were really about how you interfaced with the world outside VBA. Internally everything will do as you probably expect but there are two issues when you have to interface to external data, to which my two questions related. One is how the data are actually held (on a file or whatever), in little endian format. This may or may not be an issue depending on the answer to the second question, how you obtain the data. Maybe you don't have a problem; maybe you just don't know it yet :)

Enjoy,
Tony

--------------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.
Excel VBA Training and more Help at VBAExpress[
 
Tony,
Thanks for your interest. The CRC is performed on a HEX string created in EXCEL to test satellite command building. There really is no "outside world" in this case.

_________________
Bob Rashkin
 

Thanks, Bob,

No outside world, no problem!

Enjoy,
Tony

--------------------------------------------------------------------------------------------
We want to help you; help us to do it by reading this: Before you ask a question.
Excel VBA Training and more Help at VBAExpress[
 
OK, if anyone should ever find themselves in need of a CRC calculation, I worked it out and tested it. I also added a little string concatenation function so the user doesn't have to pass the string, just the range of cells where the command pieces are found. Then, a third function to put them together.
Code:
Function crc16(hstr1)
    'convert hstr1 to collection of 16-bit integers
    Dim hlist As New Collection
    Dim LU As New Collection
    Dim chksum, tmpsum As Integer
    cnvarr = Array("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111")
    a = Len(hstr1)
    nelm = a / 4
    If (a Mod 4 > 0) Then
        MsgBox ("must be integer multiple of 16Bits")
        Exit Function
    End If
    For i = 1 To nelm
        st1 = "&h" & Left(hstr1, 4)
        hlist.Add (CInt(st1))
        a = a - 4
        hstr1 = Right(hstr1, a)
    Next
    'build lookup table
    LU.Add (CInt(&HA001))
    LU.Add (CInt(&HF001))
    LU.Add (CInt(&HD801))
    LU.Add (CInt(&HCC01))
    LU.Add (CInt(&HC601))
    LU.Add (CInt(&HC301))
    LU.Add (CInt(&HC181))
    LU.Add (CInt(&HC0C1))
    LU.Add (CInt(&HC061))
    LU.Add (CInt(&HC031))
    LU.Add (CInt(&HC019))
    LU.Add (CInt(&HC00D))
    LU.Add (CInt(&HC007))
    LU.Add (CInt(&HC002))
    LU.Add (CInt(&H6001))
    LU.Add (CInt(&H9001))
    'initialize
    chksum = 0
    tmpsum = hlist.Item(1) Xor chksum
    hextmp = Hex(tmpsum)
    tln = Len(hextmp)
    hextmp = String(4 - tln, "0") & hextmp
    For i = 1 To 4
        cref = Mid(hextmp, i, 1)
        cix = CInt("&H" & cref)
        btmp = cnvarr(cix)
        For j = 1 To 4
            bref = Mid(btmp, j, 1)
            If bref = "1" Then
                tblix = (i - 1) * 4 + j
                chksum = chksum Xor LU.Item(tblix)
            End If
        Next
    Next
    'loop through hstr1 members
    For elm = 2 To nelm
        tmpsum = hlist.Item(elm) Xor chksum
        hextmp = Hex(tmpsum)
        tln = Len(hextmp)
        hextmp = String(4 - tln, "0") & hextmp
        For i = 1 To 4
            cref = Mid(hextmp, i, 1)
            cix = CInt("&H" & cref)
            btmp = cnvarr(cix)
            For j = 1 To 4
                bref = Mid(btmp, j, 1)
                If bref = "1" Then
                    tblix = (i - 1) * 4 + j
                    chksum = chksum Xor LU.Item(tblix)
                End If
            Next
        Next
    Next
    'return
    crc16 = Hex(chksum)
End Function
Function cmdStr(r1)
    tstr = ""
    For Each c In r1.Cells
        tstr = tstr & c.Value
    Next
    cmdStr = tstr
End Function
function crc(r)
    hstr=cmdStr(r)
    crc=crc16(hstr)
end function

_________________
Bob Rashkin
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top