HOWTO: General Bit Manipulation Routines

ID: Q185554


The information in this article applies to:
  • Microsoft Visual Basic for Applications version 5.0


SUMMARY

This article outlines routines to set or reference individual bits in both a variable and an array.


MORE INFORMATION

Microsoft provides programming examples for illustration only, without warranty either expressed or implied, including, but not limited to, the implied warranties of merchantability and/or fitness for a particular purpose. This article assumes that you are familiar with the programming language being demonstrated and the tools used to create and debug procedures. Microsoft support professionals can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific needs. If you have limited programming experience, you may want to contact the Microsoft fee-based consulting line at (800) 936-5200. For more information about the support options available from Microsoft, please see the following page on the World Wide Web:

http://www.microsoft.com/support/supportnet/overview/overview.asp
This article provides a set of general bit-manipulation routines for use in VBA code. NOTE: You should write a Visual C or C++ DLL to do bit manipulation if you require high performance. The routines are:

    Name           Description
   -----------------------------------------------------------------------

   BitMask        Returns a mask used by the other routines to set or test
                  the value of a bit in a variable.

   BitSet         Turns a bit "on" or "off".

   BitFlip        Changes the state of a bit.

   BitTest        Returns the state of a bit.

   ArrayBitSet    Turns a bit "on" or "off".

   ArrayBitFlip   Changes the state of a bit.

   ArrayBitTest   Returns the state of a bit. 
The Array routines assume 32 bits per element, starting with bits 0..31 in the lowest element, bits 32..63 in the second element, and so forth. The array does not have to be 0-based. If you specify a bit number that falls outside the bounds of the array, the operation leaves the data unchanged.

The routines have one or more of the following parameters:

     X        A Long value containing 32 bits to be manipulated.

   A()      An array containing bits to be manipulated.

   Value    TRUE to set a bit, FALSE to reset a bit.

   N        A number indicating the bit to manipulate. In the case of a
            single Long variable, valid ranges are 0..31. In the case of an
            array, valid values are 0..(number of elements * 32) - 1. Any
            value of N outside this range is ignored. In the case of a
            function, a FALSE is returned. 
The BitTest and ArrayBitTest functions return TRUE (-1) if the bit is 1 and FALSE (0) if the bit is 0 (zero).

Sample Code

  1. Create a new project and add the following code to a module:
    
          Function BitMask(ByVal N As Long) As Long
          Dim I As Long, Mask As Long
            If N < 0 Or N > 31 Then
              BitMask = 0
            ElseIf N = 31 Then
              BitMask = &H80000000
            Else
              Mask = 1
              For I = 1 To N
                Mask = Mask + Mask
              Next I
              BitMask = Mask
            End If
          End Function
    
          Sub BitSet(X As Long, ByVal N As Long, ByVal Value As Boolean)
            If Value Then
              X = X Or BitMask(N)
            Else
              X = X And Not BitMask(N)
            End If
          End Sub
    
          Sub BitFlip(X As Long, ByVal N As Long)
            X = X Xor BitMask(N)
          End Sub
    
          Function BitTest(X As Long, ByVal N As Long) As Boolean
          ' Return False if invalid N
            BitTest = (X And BitMask(N)) <> 0
          End Function
    
          Sub ArrayBitSet(A() As Long, ByVal N As Long, _
                          ByVal Value As Boolean)
          Dim Element As Integer
            Element = N \ 32 + LBound(A)
            If Element <= UBound(A) And N >= 0 Then
              BitSet A(Element), N Mod 32, Value
            End If
          End Sub
    
          Sub ArrayBitFlip(A() As Long, ByVal N As Long)
          Dim Element As Integer
            Element = N \ 32 + LBound(A)
            If Element <= UBound(A) And N >= 0 Then
              BitFlip A(Element), N Mod 32
            End If
          End Sub
    
          Function ArrayBitTest(A() As Long, ByVal N As Long) As Boolean
          ' Returns False if invalid N.
          Dim Element As Integer
            Element = N \ 32 + LBound(A)
            If Element <= UBound(A) And N >= 0 Then
              ArrayBitTest = BitTest(A(Element), N Mod 32)
            Else
              ArrayBitTest = False
            End If
          End Function 


  2. You can the use the functions in code as follows. Add the following code to the module:
    
          Sub Main()
             Dim Bits As Long, aBits(0 To 2) As Long
             Bits = &H8000C000&
             BitSet Bits, 5, True
             BitSet Bits, 15, False
             ArrayBitSet aBits(), 45, True
             Debug.Print Hex$(Bits), BitTest(Bits, 4)
             Debug.Print Hex$(aBits(0)), Hex$(aBits(1)), Hex$(aBits(2))
          End Sub 


  3. Run the procedure "Main".

    RESULTS: The debug window displays the following data.
    
          80004020      FALSE
          0      2000      0 



REFERENCES

For more information about getting help with Visual Basic for Applications, please see the following article in the Microsoft Knowledge Base:

Q163435 VBA: Programming Resources for Visual Basic for Applications

Additional query words: vba kbVBA kbVBp kbDSupport kbDSD

Keywords :
Version : WINDOWS:5.0
Platform : WINDOWS
Issue type : kbhowto kbinfo


Last Reviewed: November 13, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.