-
Jul 2nd, 2005, 10:32 AM
#1
[VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
A DWord in Windows is 32 bytes, which is equivalent to a Long in Visual Basic. The leftmost 16 bits comprise the low word (an Integer in VB), while the the rightmost 16 bits are the high word.
Most examples use an And operation to get or set the words in a DWord. However, the quickest way to get/set the high and low word of a DWord (Double Word) is to do a direct memory move operation. To do this we need one API declaration:
VB Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByRef lpvDest As Any, _
ByRef lpvSrc As Any, _
ByVal cbLength As Long)
And four one-line functions, made into properties for easy and logical use.
VB Code:
Public Property Get LoWord(ByRef DWord As Long) As Integer
CopyMemory LoWord, ByVal VarPtr(DWord), 2
End Property
Public Property Let LoWord(ByRef DWord As Long, ByVal Word As Integer)
CopyMemory DWord, Word, 2
End Property
Public Property Get HiWord(ByRef DWord As Long) As Integer
CopyMemory HiWord, ByVal VarPtr(DWord) + 2, 2
End Property
Public Property Let HiWord(ByRef DWord As Long, ByVal Word As Integer)
CopyMemory ByVal VarPtr(DWord) + 2, Word, 2
End Property
Using them is easy, here are some useless examples:
VB Code:
Dim lDWord As Long
Dim iWord As Integer
' Set the low word
LoWord(lDWord) = 1
' Set the high word
HiWord(lDWord) = 2
' Get the low word
iWord = LoWord(lDWord)
' Get the high word
iWord = HiWord(lDWord)
Likewise, we can do the same for the high and low bytes of a Word:
VB Code:
Public Property Get LoByte(ByRef Word As Integer) As Byte
CopyMemory LoByte, ByVal VarPtr(Word), 1
End Property
Public Property Let LoByte(ByRef Word As Integer, ByVal LowByte As Byte)
CopyMemory Word, LowByte, 1
End Property
Public Property Get HiByte(ByRef Word As Integer) As Byte
CopyMemory HiByte, ByVal VarPtr(Word) + 1, 1
End Property
Public Property Let HiByte(ByRef Word As Integer, ByVal HighByte As Byte)
CopyMemory ByVal VarPtr(Word) + 1, HighByte, 1
End Property
Have fun
Last edited by penagate; Jul 7th, 2005 at 06:18 AM.
-
Jul 3rd, 2005, 03:14 AM
#2
Swap Words and Bytes
Couple of functions using the above properties to swap the words or bytes of a DWord or Word, respectively.
VB Code:
Public Function SwapWords(ByRef DWord As Long) As Long
Dim lTWord As Integer
lTWord = HiWord(DWord)
HiWord(DWord) = LoWord(DWord)
LoWord(DWord) = lTWord
SwapWords = DWord
End Function
Public Function SwapBytes(ByRef Word As Integer) As Integer
Dim lTByte As Byte
lTByte = HiByte(Word)
HiByte(Word) = LoByte(Word)
LoByte(Word) = lTByte
SwapBytes = Word
End Function
Last edited by penagate; Jul 7th, 2005 at 06:16 AM.
-
Jul 7th, 2005, 06:16 AM
#3
Bitshifting
Here is a bitshifting function. It is not mine, but a modified version of the one from Bruce McKinney's book Hardcore Visual Basic. If you want to read that book (He says a lot of good things so I suggest you do ), the link is in my sig.
VB Code:
Public Function BitShiftWord(ByVal Word As Integer, ByVal ShiftBy As Integer) As Integer
Dim lDWord As Long
lDWord = Word * 2 ^ ShiftBy
If (lDWord And &H8000&) Then
BitShiftWord = CInt(lDWord And &H7FFF&) Or &H8000
Else
BitShiftWord = lDWord And &HFFFF&
End If
End Function
Because of limitations with VB, the biggest size number that that function can handle is a Word (16 bit integer). Hopefully, an API one will follow
-
Dec 21st, 2008, 11:41 AM
#4
Fanatic Member
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
Can the code work with high/low numbers - for the same reason I am still awaiting an answer?
-
Dec 21st, 2008, 08:11 PM
#5
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
Can you clarify that question? I can't follow what you mean.
However, these code snippets by penagate aren't very fast, although not the worst I've seen either. Making API calls isn't as fast as one would think, using them for small purposes doesn't pay back.
Here are slightly different versions that work very fast compiled:
Code:
Public Property Get HighInteger(ByRef Value As Long) As Integer
HighInteger = ((Value And &H7FFF0000) \ &H10000) Or (&H8000 And (Value < 0))
End Property
Public Property Let HighInteger(ByRef Value As Long, ByVal NewValue As Integer)
Value = (Value And &HFFFF&) Or ((NewValue And &H7FFF) * &H10000) Or (&H80000000 And (NewValue < 0))
End Property
Public Property Get LowInteger(ByRef Value As Long) As Integer
LowInteger = (Value And &H7FFF) Or (&H8000 And ((Value And &H8000&) = &H8000&))
End Property
Public Property Let LowInteger(ByRef Value As Long, ByVal NewValue As Integer)
Value = (Value And &HFFFF0000) Or (NewValue And &HFFFF&)
End Property
Usage is different: these methods manipulate a value directly.
This changes the high integer part in lngValue to be 1:
HighInteger(lngValue) = 1
While this gets the current high integer:
intHigh = HighInteger(lngValue)
The same logic works with LowInteger.
-
Dec 21st, 2008, 09:11 PM
#6
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
Usage looks the same, but I agree (now) RtlMoveMemory is slow for small operations; best reserved for shifting large chunks of data.
-
Dec 21st, 2008, 09:33 PM
#7
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
I guess I somehow managed to read wrong code earlier... I also did a search for a few other ones for reference (and to confirm to myself that some pieces of code never cease to amaze...string operations are over used in wrong places).
Anyways, to continue a bit with real content, I think bitshifting is best done inline. It can with some trial and error be replicated with bitmasking (And) and multiplying, or to do it to other direction by using \ and And. Not as fast as real bitshifting, but faster than trying to replicate it in other ways, and simple enough to be done inline.
-
Dec 22nd, 2008, 06:07 AM
#8
Fanatic Member
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
Originally Posted by Merri
Can you clarify that question? I can't follow what you mean.
Well, in another thread that I have been awaiting an answer for days but to no avail, I am wondering what command I would use if I were to use higher/lower buttons.
Here are the steps involved:
1. 2 players involved
2. A question is asked involving numbers as answers (whether general knowledge or random numbers).
3. Player guesses the number (say a players guesses "24").
4. The number (in this example, 24) is displayed in an image on that player's side (individual digits "2" then "4").
5. Opponent guesses higher or lower by clicking the corresponding "higher" or "lower" button.
6. The word "Higher" or "Lower" is displayed on that opponent's side.
7. Result is revealed a few seconds later (images of digits are used for registering the numbers and same for the result).
I apologize if it has to do with games, but for the most part it has to do with VB code, so technically this post is in the right forum.
-
Jan 1st, 2009, 02:03 PM
#9
Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting
Originally Posted by JonSea31
I apologize if it has to do with games, but for the most part it has to do with VB code, so technically this post is in the right forum.
No it isn't; this forum isn't for questions.
The "high" and "low" being discussed in this thread aren't related to the "higher" and "lower" concepts in your question.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|