Hello,
I'm not a bits & bytes person, but i need to figure this out:
So, we have a file loaded in our buffer and the GUIDE says:
at DWORD @ POS xx
so: we read 2 BYTES
convert to an INTEGER
then do a DecToBin conversion?
Whats the theory?
Printable View
Hello,
I'm not a bits & bytes person, but i need to figure this out:
So, we have a file loaded in our buffer and the GUIDE says:
at DWORD @ POS xx
so: we read 2 BYTES
convert to an INTEGER
then do a DecToBin conversion?
Whats the theory?
DWORD is 4 bytes, not 2.
By bits, do you mean you have to display each bit in the 32bit Long (DWORD)?
More info maybe.
For an integer or long, you'll need to handle the high bit separately.
Integer high bit is &H8000. If it's set then your integer will be negative or you can test for it.
Example: (-1234 And &H8000)<>0 also -1234 is obviously negative, so bit 16 is a 1
For the remainder, you can use a loop
Bits are listed from highest to lowest, left to rightCode:Dim iMask As Integer, myInt As Integer
iMask = &H4000 ' equivalent of bit 15 (2^(15-1))
myInt = CInt(Rnd * &H7FFF)
If (myInt And 1) Then myInt = -myInt ' toggle to negative for testing
Debug.Print "Value: "; myInt
If myInt < 0 Then Debug.Print "1"; Else Debug.Print "0";
Do
If (myInt And iMask) = 0 Then Debug.Print "0"; Else Debug.Print "1";
iMask = iMask \ 2
Loop Until iMask = 0
Debug.Print
Hmmm. I didn't offer a clear way of modifying them, did I?
To modify the 16th bit of an Integer: Toggle the high bit
If you want the high bit set: myInt = myInt Or &H8000
Strip the high bit if not wanted: myInt = (myInt And &H7FFF). Remember high bit is &H8000
If you want to toggle it regardless of what it is set at: myInt = myInt Xor &H8000
For all other bits (15-1), a bit different (pun intended) ;)
To include a bit (ensure it is 1): myInt = myInt Or (2^(bit# - 1))
To remove a bit (ensure it is 0): myInt = myInt And Not (2^(bit# - 1))
To toggle a bit regardless of what it is set at: myInt = myInt Xor (myInt And (2^(bit# -1))
In above samples, bit# is a value between 1 and 15
Wikipedia has a somewhat easy to understand description of bitwise operations
Hey.. sorry I've been away on this for a while.. and I'm totally lost with these bits :((
Can we put this in a working Sub/function please?
i.e
Code:Private theBits(15) as integer/long 'Do we handle as integers or longs?
''So the theBits() array can display each bit; i.e 1000001011010110
Private Sub GetBits(byval WORD_Data as string)
'''so we do a loop which adds each of the bits to the theBits() array
''so that they can easily be manipulated
End Sub
Private Sub WriteBits(theArray() as integer/long) as String
'We must write the array back to a WORD string ; {2 chars}
End Sub
DWORD_Data as string? 2 chars? theBits(15)?
How many bytes are encoded into your 2 character string? 2 or 4
Why string?
Just want to get a grasp of the bigger picture.
Edit: some1uk03, I'm being a little pedantic with the above I'm guessing you mean Word_Data and there is 1 byte represented by each 2 byte character. theBits(15) could also be defined as Boolean.
Sorry that's a typo... meant to be WORD not DWORD
So the idea or the Bigger picture is this:
I have specific file with CHUNKS etc.. assuming:
So I need to read pos 35. This being a WORD type, will be 35&36.Code:FilePos: Data Type
xPOS 30 Byte
xPOS 31 Long
xPOS 35 WORD
'etc..
'etc...
Then I need to convert/get the bits out of these!! presumably pos35=1Byte/8 bits & pos36=1Byte/8 bits ; in total 16
Make sense?
It does. Why string though? Are you reading the file into one?
Yes the whole file is read to a string.
And I normally do a ToInteger / ToLong conversions.
I could have that as byval WORD_Data as integer/long no prob.
I could even have them as 2 separate inputs? byval part1 as integer/long, byval part2 as integer/long
It's extracting the bits I'm more worried about, rather than the input.
Sorry I'm getting off track, the following is for an Integer rather than string and it assumes theBits() is boolean.
Code:Private Sub GetBits(byval Word as Integer)
Dim i as Long, bit as Long
bit = 1
For i = 0 to 14
theBits(i) = cbool(Word And bit) 'use this if theBits is boolean
'If (Word And bit) <> 0 Then theBits(i) = 1 Else theBits(i) = 0 'use this is if theBits is byte, integer, long
'theBits(i) = -cBool(Word And bit) 'same as above line but not very clear
bit = bit * 2
Next
theBits(15) = cbool(Word And &h8000) 'handle the high bit
End Sub
Not testedCode:Private Sub WriteBits() as Integer
Dim i as Long, bit as Long, wordOut as Integer
bit = 1
For i = 0 to 14
If theBits(i) Then wordOut = wordOut Or bit
bit = bit * 2
Next
If theBits(15) Then wordOut = wordOut Or &h8000
WriteBits = wordOut
End Sub
If the file contains binary data, then reading it as a string is probably not a good idea. Reading a Word (Integer) or DWord (Long) value from a specific location in the file is simple: Get #FileNumber, Pos, Value where Value is a variable of the appropriate type.
Anyway, here is something that may help with bit-wise operations:
You can use it like this:Code:Private IntegerBit(15) As Integer
Private LongBit(31) As Long
Private Sub Form_Load()
Dim i As Long, n As Long
n=1
For i = 0 To 14
IntegerBit(i) = n
LongBit(i) = n
n=n+n
Next i
IntegerBit(15) = &H8000
For i = 15 To 29
LongBit(i) = n
n=n+n
Next i
LongBit(30) = n
LongBit(31) = &H80000000
End Sub
The arrays also make it easy to 'extract' the bits into a string of 1s and 0s. Start with a string of 0s and use Mid() to put 1s in where needed.Code:value = value Or bit(x) ' make the bit '1'
value = value And Not bit(x) ' make the bit '0'
value = value XOr bit(x) ' change the bit
You could go completely over the top and treat Bytes as Bytes....(Saves having to mess about with sign bits etc.)
:)Code:Option Explicit
Private Sub Command_Click()
Dim strData As String
Dim bytData(1) As Byte
Dim intI As Integer
strData = "AB"
'
' Stick the data into a byte array
'
bytData(0) = CByte(Asc(Mid$(strData, 1, 1)))
bytData(1) = CByte(Asc(Mid$(strData, 2, 1)))
Debug.Print Hex(bytData(0)); Hex(bytData(1))
'
' Display the bits
' bit 0 = MSb, bit 15=LSb
'
For intI = 0 To 15
Debug.Print CStr(GetBit(bytData, intI));
Next intI
Debug.Print
'
' Set bit 1 to zero
'
Call ChangeBit(bytData, 1, 0)
Debug.Print Hex(bytData(0)); Hex(bytData(1))
'
' Set bit 15 to 1
'
Call ChangeBit(bytData, 15, 1)
Debug.Print Hex(bytData(0)); Hex(bytData(1))
End Sub
Private Function GetBit(bytD() As Byte, intBit As Integer) As Integer
Dim intElement As Integer
Dim intElementBit As Integer
If intBit >= 0 And intBit <= 15 Then
intElement = intBit \ 8
intElementBit = 7 - (intBit - (intElement * 8))
If (bytD(intElement) And (2 ^ intElementBit)) = 0 Then
GetBit = 0
Else
GetBit = 1
End If
End If
End Function
Private Sub ChangeBit(bytD() As Byte, intBit As Integer, intV As Integer)
Dim intElement As Integer
Dim intElementBit As Integer
If intBit >= 0 And intBit <= 15 And (intV = 0 Or intV = 1) Then
intElement = intBit \ 8
intElementBit = 7 - (intBit - (intElement * 8))
If intV = 1 Then
bytD(intElement) = bytD(intElement) Or 2 ^ intElementBit
Else
bytD(intElement) = bytD(intElement) And Not (2 ^ intElementBit)
End If
End If
End Sub
(Just stick the data back into the string when you've finished messing about with the bits)
and it works... :)) thanks guys..