By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,404 Members | 1,873 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,404 IT Pros & Developers. It's quick & easy.

Bit manipulation question.

P: 5
Hi,
I've been trying to do something that seems like ist should be simple but I'm not having any luck.

I have an integer field with values from 0 to 65535 which is 16 flags.
What I want to do is test for each of these flags individually and display if they are true or false.

However, when I try ANDing the field with 1, 2, 4, etc to get the bits, it always returns -1 (unless the field is 0 then it returns 0).

Thought of manually making a lookup table but the thought of typing 65535 rows of yes/no made my hands start to ache.

Sounds simple, but I'm pulling my hair out trying to get it to work.

Any suggestions much appreciated.
Dec 17 '07 #1
Share this Question
Share on Google+
7 Replies


FishVal
Expert 2.5K+
P: 2,653
Hi, Angahran.

It looks like the operation is performed as boolean (True=-1, False=0). I couldn't reproduce your situation. I get bitwise operators AND, OR, XOR working as expected. Could you post an exact code you have?

Regards,
Fish
Dec 17 '07 #2

P: 5
Here's the dummy code I've been trying out.

classes is the field in the table and bit1 is my output field.
Eventually I'd like to be able to check all 16 bits, but getting 1 to work would be a good start :P

Private Sub Command6_Click()
On Error GoTo Err_Command6_Click

bit1.Value = classes.Value & 1

Exit_Command6_Click:
Exit Sub

Err_Command6_Click:
MsgBox Err.Description
Resume Exit_Command6_Click

End Sub
Dec 17 '07 #3

FishVal
Expert 2.5K+
P: 2,653
:)

VBA syntax differs form C one.
"&" in VBA is "AND"
"|" in VBA is "OR"
"^" in VBA is "XOR"

The following simple function checks specified bit in Integer(word).
Expand|Select|Wrap|Line Numbers
  1. Public Function CheckBit(ByVal intInput As Integer, _
  2.                          ByVal intBitNumber As Integer) As Boolean
  3.  
  4.     CheckBit = intInput And 2 ^ intBitNumber
  5.  
  6. End Function
  7.  
Dec 17 '07 #4

P: 5
Thanks :)
Was getting overflow on anything above 32767 so changed to Double.

Public Function DblCheckBit(ByVal dblInput As Double, _
ByVal dblBitNumber As Double) As Boolean
DblCheckBit = dblInput And 2 ^ dblBitNumber
End Function

Now going to dummy up a form with 'Classes' and 16 True/Falses and see how that looks.

Thanks again.
Dec 17 '07 #5

FishVal
Expert 2.5K+
P: 2,653
Better change it to Long, though storing 16 bit values you don't need it as soon as Integer values above 32767 are represented as negative (VBA doesn't have unsighned types).

Regards,
Fish
Dec 17 '07 #6

ADezii
Expert 5K+
P: 8,638
Hi,
I've been trying to do something that seems like ist should be simple but I'm not having any luck.

I have an integer field with values from 0 to 65535 which is 16 flags.
What I want to do is test for each of these flags individually and display if they are true or false.

However, when I try ANDing the field with 1, 2, 4, etc to get the bits, it always returns -1 (unless the field is 0 then it returns 0).

Thought of manually making a lookup table but the thought of typing 65535 rows of yes/no made my hands start to ache.

Sounds simple, but I'm pulling my hair out trying to get it to work.

Any suggestions much appreciated.
I have an integer field with values from 0 to 65535 which is 16 flags
The maximum allowable value for an Integer is 32767 (a Bit is assigned to indicate whether or not the Number is Positive or Negative).

Here is a little something I threw together for you. Take a look at it and see if it is what you need. Simply pass to the Function a Long Integer and let it do the work for you:
Expand|Select|Wrap|Line Numbers
  1. Public Function fConvertToBinary(ByVal lngValueToConvert As Long) As String
  2. 'Converts a Long Integer into its Binary equivalent and returns each Bit
  3. 'position indicating whether it is set or not
  4. Dim strBinary As String, strReturn As String, intCounter As Integer
  5. Dim intBits As Integer, intBitPosition As Integer
  6.  
  7. intBits = 24
  8. intCounter = (Len(str$(lngValueToConvert)) - 1) * 4
  9.  
  10. 'Create a String that is large enough to hold the Bits so that we can use the
  11. 'Mid Statement to replace the zeros with the real Bit Values
  12. strBinary = String(intCounter, "0")
  13.  
  14. Do While lngValueToConvert
  15.   'The remainder is the Bit Value,so set this in the String
  16.   Mid$(strBinary, intCounter, 1) = CStr(lngValueToConvert Mod 2)
  17.   lngValueToConvert = lngValueToConvert \ 2
  18.   'Decrement intCounter, so we'll know which Bit to set in strBinary
  19.   intCounter = intCounter - 1
  20. Loop
  21.  
  22. For intCounter = 1 To (intBits \ 4)
  23.   strReturn = strReturn & Left$(strBinary, 4)
  24.   strBinary = Mid$(strBinary, 5)
  25. Next intCounter
  26.  
  27. Debug.Print "*******************************"
  28. Debug.Print strReturn
  29. Debug.Print "*******************************"
  30. For intCounter = Len(strReturn) To 1 Step -1
  31.   intBitPosition = intCounter - (Len(strReturn) + 1)
  32.   Debug.Print "Bit #" & Format$(intBitPosition, "00") & " - " & _
  33.               IIf(Mid$(strReturn, intCounter, 1) = 1, "True", "False")
  34. Next
  35. End Function
Expand|Select|Wrap|Line Numbers
  1. 'Function Call
  2. Call fConvertToBinary(65535)
OUTPUT:
Expand|Select|Wrap|Line Numbers
  1. *******************************
  2. 00001111111111111111
  3. *******************************
  4. Bit #-01 - True
  5. Bit #-02 - True
  6. Bit #-03 - True
  7. Bit #-04 - True
  8. Bit #-05 - True
  9. Bit #-06 - True
  10. Bit #-07 - True
  11. Bit #-08 - True
  12. Bit #-09 - True
  13. Bit #-10 - True
  14. Bit #-11 - True
  15. Bit #-12 - True
  16. Bit #-13 - True
  17. Bit #-14 - True
  18. Bit #-15 - True
  19. Bit #-16 - True
  20. Bit #-17 - False
  21. Bit #-18 - False
  22. Bit #-19 - False
  23. Bit #-20 - False
Dec 18 '07 #7

P: 5
Thanks for all the help.

Slowly beating this form into shape, but seems like there's a new problem hiding behind every line of code.

Apparently, I have hit some maximum number of fields limit on my form when I tried linking the lookup tables I had created.

So, I thought I'd try working without the lookup tables and check the bits as part of the main query.

Here's a dummy part showing what I was trying to do.
Expand|Select|Wrap|Line Numbers
  1. SELECT classes FROM qryItems WHERE (CheckBit(classes,0) = 'True');
Unfortunately, no matter how I specify the 'True' part I get a type mismatch error and Access '07 crashes :(
I've tried single quotes, double quotes, no quotes, all with the same type mismatch error.
Mar 9 '08 #8

Post your reply

Sign in to post your reply or Sign up for a free account.