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.

Verify my functions
kReynolds
Try these articles:
http://www.somacon.com/p125.php
http://www.cprogramming.com/tutorial/bitwise_operators.html
http://en.wikipedia.org/wiki/Bitwise_operation
Regards,
-chris
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
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
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
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
zadcoe
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