Verify my functions

I made three functions that deal with bits. I want to know if they are good or if they can be improved. Thank You.

Private Function extractBit(ByVal value As Byte, ByVal bit As Byte) As Boolean
If bit = 7 Then bit = 128
If bit = 6 Then bit = 64
If bit = 5 Then bit = 32
If bit = 4 Then bit = 16
If bit = 3 Then bit = 8
If bit = 2 Then bit = 4
If bit = 1 Then bit = 2
If bit = 0 Then bit = 1

If (value And bit) <> 0 Then
Return True
Else
Return False
End If
End Function

Private Function setBit(ByVal value As Byte, ByVal bit As Byte) As Byte
If bit = 7 Then bit = 128
If bit = 6 Then bit = 64
If bit = 5 Then bit = 32
If bit = 4 Then bit = 16
If bit = 3 Then bit = 8
If bit = 2 Then bit = 4
If bit = 1 Then bit = 2
If bit = 0 Then bit = 1

value = value Or bit
Return value
End Function

Private Function unSetBit(ByVal value As Byte, ByVal bit As Byte) As Byte
If bit = 7 Then bit = 128
If bit = 6 Then bit = 64
If bit = 5 Then bit = 32
If bit = 4 Then bit = 16
If bit = 3 Then bit = 8
If bit = 2 Then bit = 4
If bit = 1 Then bit = 2
If bit = 0 Then bit = 1

value = value And Not bit
Return value
End Function

The functions are pretty much self explanitory. Here are some possible usages anyway:

CheckBox1.Checked = extractBit(45, 3) 'If the 4th bit is set then check the box
setBit(0, 5) 'This would set the sixth bit resulting in 00100000
unSetBit(32, 5) 'This would unSet the sixth bit resulting in 00000000


If any of this seems wrong or just unneccesary, please let me know.



Answer this question

Verify my functions

  • kReynolds

  • Phoenix wolfe

    How about simplifying them

    You have a simple call to set or reset a bit and simply give it the byte, which bit you want to set and whether its setting or unseting the bit.

    Private Function SetUnsetBit(ByVal value As Byte, ByVal bitItem As Integer, ByVal Action As Short) As Byte
    Dim bit As Byte = 2 ^ bitItem
    If Action = 1 Then '//SET
    value = value Or bit
    ElseIf Action = 0 Then '//UNSET
    value = value And Not bit
    End If
    Return value
    End Function

    Function IsBitSet(ByVal value As Byte, ByVal bitItem As Short) As Boolean
    Dim bit As Byte = 2 ^ bitItem
    If (value And bit) <> 0 Then
    Return True
    Else
    Return False
    End If
    End Function


  • RyanB88

    it has nothing to do with database programming, it has to do with how computers work (call stacks vs register math) Every good computer programmer should know to use bitmasks and hex encoding. its really not that difficult when you see the pattern.

    (For the original poster)

    Each place in a hex number represents a byte. the level of the digit in a hex mask represents the bit:

    &H01 -> 00000001 -> 1 - > 2 ^ 0

    &H02 -> 00000010 -> 2 - > 2 ^ 1

    &H04 -> 00000100 -> 4 - > 2 ^ 2

    &H08 -> 00001000 -> 8 - > 2 ^ 3

    &H10 -> 00010000 -> 16 - > 2 ^ 4

    &H20 -> 00100000 -> 32 - > 2 ^5

    &H40 -> 01000000 -> 64 - > 2 ^ 6

    &H80 -> 10000000 -> 128 - > 2 ^ 7

    "AND" gets the common

    "OR" gets the combination

    unsetting a particular bit is a little tricky - XOR gives only bits that are set in both. Given that FFFFFFFF is every possible bit set, XOR' ing FFFFFFFF against the toggle bit removes the toggled bit from FFFFFFFF. so AND'ing that against the number will unset the bit of the source number.

    the benefit is that evaluation can take place in one execution. no need to push onto the call stack and do all that spaghetti "if" stuff.

    And by the way, using bitmasks in a database is not a good idea.



  • phil_lee

    I think case statements would be more efficient.



  • Mark Kaplan

    Using bitmasks is the exact solution to the problem. And it is important for developers to learn binary operations.

    Private Function extractBit(ByVal value As Byte, ByVal bit As Byte) As Boolean
      'do an and comparison of the value and 1 
      'shifted to the left "bit" times

        return value and (1<<bit)<>0
    end function

    So we have the result in one line of code with the only constants being 1 and 0.

    Private Function setBit(ByVal value As Byte, ByVal bit As Byte) As Byte
            Return value or (1<<bit)
        End Function

    Again one line of code gets the results we want... If you want to be anal you can put some value checks (basically making sure that bit is between 0 and 7) so you don't get strange results due to overflows.

    Too bad VB doesn't have an "inline" equivalent because that would optimize the function even more it makes little sense to do a function lookup for one line of code.

    Doing set and unset operations in a single function gives something like

    Private Function setBit(ByVal value As Byte, ByVal set as Boolean, ByVal bit As Byte) As Byte
            Return DirectCast(IIF(set,value or (1<<bit),value And Not (1<<bit)),Byte)
        End Function

     



  • Jacques van t Ende

    hi,

    very interesting topic, i would like to learn more about bit masks is there any recomended book for that

    best regards



  • Fabita

    "then stop wasting energy.

    I wasnt even talking to you. Go back to your knowledge explorer."

    I'll make my own choices. I'm a big girl now. As far as KnowledgeNavigator is concerned, I'm using it to make this response.



  • James Divine

    Blair,

    I was an operating systems engineer writing drivers for mainframes for fourteen years.

    I was using stacks and masks when you were six years old.

    Discussions on bit masks for gaming is not something I'm going to devote a lot of energy to.



  • new2

    spotty,
    Could you tell me what ^ does Or point me to a link. I found out that
    bit ^ 2
    is different from
    2 ^ bit
    as they produced different results. I want to know what ^ does.

    By the way, your example worked perfectly. The only thing I changed was instead of Action being a Short (it only has two options) it is now a boolean value. Also, this stuff is really mind-numbing. Could you possibly provide a usage example for the SetUnsetBit function

    Thank you again.


  • Andrew

    An additional item I'd add to the BitSetting function (as provided by Spotty: I think that's the clearest, and thus the best, example) is a check to ensure that the selected BitItem is within a valid range: if you are setting bits in a byte value, then the check could be:

    if BitItem < 0 or BitItem > 7 then return Value ' Don't do anything



  • Nehal Jain

    many Thx Chris

  • zadcoe

    ReneeC wrote:

    Blair,

    I was an operating systems engineer writing drivers for mainframes for fourteen years.

    I was using stacks and masks when you were six years old.

    Discussions on bit masks for gaming is not something I'm going to devote a lot of energy to.

    then stop wasting energy.

    I wasnt even talking to you. Go back to your knowledge explorer.



  • Zeeshan

    The ^ raises to the power of

    so 2^0 = 1, 2^1 = 2, 2^2 = 4, 2^3 = 8 ......

    It saves having to hardcode any values.

    Module Module1

    Sub Main()
    Dim x As Byte = 0
    Dim y As Byte = 0

    Console.WriteLine("Write Bit 0 - 1 value")
    y = SetUnsetBit(x, 0, True) '//Shgould result in value of 1
    Console.WriteLine(y)
    Console.WriteLine(IsBitSet(y, 0)) '//Should Be True
    y = SetUnsetBit(x, 0, False) '//Shgould result in value of 0
    Console.WriteLine(y)
    Console.WriteLine(IsBitSet(y, 0)) '//Should Be False

    Console.WriteLine("Write Bit 7 - 128 value")
    y = SetUnsetBit(x, 7, True) '//Shgould result in value of 128
    Console.WriteLine(y)
    Console.WriteLine(IsBitSet(y, 7)) '//Should Be True
    y = SetUnsetBit(x, 7, False) '//Shgould result in value of 0
    Console.WriteLine(y)
    Console.WriteLine(IsBitSet(y, 7)) '//Should Be False


    y = SetUnsetBit(x, 1, True) '//Shgould result in value of 2
    y = SetUnsetBit(y, 7, True) '//Shgould result in value of 128
    Console.WriteLine(y) 'SHould Result in 130
    y = SetUnsetBit(y, 1, False) '//Shgould Subtract value of 2
    Console.WriteLine(y) 'SHould Result in 128


    End Sub

    Private Function SetUnsetBit(ByVal value As Byte, ByVal bitItem As Integer, ByVal Action As Boolean) As Byte
    Dim bit As Byte = 2 ^ bitItem
    If Action = True Then '//SET
    value = value Or bit
    Else '//UNSET
    value = value And Not bit
    End If
    Return value
    End Function

    Function IsBitSet(ByVal value As Byte, ByVal bitItem As Short) As Boolean
    Dim bit As Byte = 2 ^ bitItem
    If (value And bit) <> 0 Then
    Return True
    Else
    Return False
    End If
    End Function

    End Module


  • hoowahfun

    "Waste nary a cycle or a byte"

    You ALL should get familiar with Hex.

    &h01 -> 1

    &h02 -> 2

    &h04 -> 4

    &h08 -> 8

    &h10 -> 16

    &h20 -> 32

    &h40 -> 64

    &h80 -> 128

    &h100 -> 256

    so . . .

    simply and/or against those.

    CheckBox1.Checked = (somebitmask and &H08) <> 0 'check bit 3 [bit masks are zero indexed by the way]

    somebitmask = (somebitmask or &H20) 'set bit 5

    somebitmask = somebitmask and (&Hffffffff xor &H20) 'unset bit 5



  • Verify my functions