Results 1 to 9 of 9

Thread: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting

  1. #1

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Arrow [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:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    2.     (ByRef lpvDest As Any, _
    3.      ByRef lpvSrc As Any, _
    4.      ByVal cbLength As Long)

    And four one-line functions, made into properties for easy and logical use.
    VB Code:
    1. Public Property Get LoWord(ByRef DWord As Long) As Integer
    2.     CopyMemory LoWord, ByVal VarPtr(DWord), 2
    3. End Property
    4.  
    5. Public Property Let LoWord(ByRef DWord As Long, ByVal Word As Integer)
    6.     CopyMemory DWord, Word, 2
    7. End Property
    8.  
    9. Public Property Get HiWord(ByRef DWord As Long) As Integer
    10.     CopyMemory HiWord, ByVal VarPtr(DWord) + 2, 2
    11. End Property
    12.  
    13. Public Property Let HiWord(ByRef DWord As Long, ByVal Word As Integer)
    14.     CopyMemory ByVal VarPtr(DWord) + 2, Word, 2
    15. End Property

    Using them is easy, here are some useless examples:
    VB Code:
    1. Dim lDWord As Long
    2. Dim iWord As Integer
    3.  
    4. ' Set the low word
    5. LoWord(lDWord) = 1
    6.  
    7. ' Set the high word
    8. HiWord(lDWord) = 2
    9.  
    10. ' Get the low word
    11. iWord = LoWord(lDWord)
    12.  
    13. ' Get the high word
    14. iWord = HiWord(lDWord)

    Likewise, we can do the same for the high and low bytes of a Word:
    VB Code:
    1. Public Property Get LoByte(ByRef Word As Integer) As Byte
    2.     CopyMemory LoByte, ByVal VarPtr(Word), 1
    3. End Property
    4.  
    5. Public Property Let LoByte(ByRef Word As Integer, ByVal LowByte As Byte)
    6.     CopyMemory Word, LowByte, 1
    7. End Property
    8.  
    9. Public Property Get HiByte(ByRef Word As Integer) As Byte
    10.     CopyMemory HiByte, ByVal VarPtr(Word) + 1, 1
    11. End Property
    12.  
    13. Public Property Let HiByte(ByRef Word As Integer, ByVal HighByte As Byte)
    14.     CopyMemory ByVal VarPtr(Word) + 1, HighByte, 1
    15. End Property

    Have fun
    Last edited by penagate; Jul 7th, 2005 at 06:18 AM.

  2. #2

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    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:
    1. Public Function SwapWords(ByRef DWord As Long) As Long
    2. Dim lTWord      As Integer
    3.     lTWord = HiWord(DWord)
    4.     HiWord(DWord) = LoWord(DWord)
    5.     LoWord(DWord) = lTWord
    6.     SwapWords = DWord
    7. End Function
    8.  
    9. Public Function SwapBytes(ByRef Word As Integer) As Integer
    10. Dim lTByte      As Byte
    11.     lTByte = HiByte(Word)
    12.     HiByte(Word) = LoByte(Word)
    13.     LoByte(Word) = lTByte
    14.     SwapBytes = Word
    15. End Function
    Last edited by penagate; Jul 7th, 2005 at 06:16 AM.

  3. #3

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    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:
    1. Public Function BitShiftWord(ByVal Word As Integer, ByVal ShiftBy As Integer) As Integer
    2.     Dim lDWord As Long
    3.     lDWord = Word * 2 ^ ShiftBy
    4.     If (lDWord And &H8000&) Then
    5.         BitShiftWord = CInt(lDWord And &H7FFF&) Or &H8000
    6.       Else
    7.         BitShiftWord = lDWord And &HFFFF&
    8.     End If
    9. 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

  4. #4
    Fanatic Member
    Join Date
    Dec 2008
    Location
    St. John's, Newfoundland, Canada
    Posts
    965

    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?

  5. #5
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  6. #6

    Thread Starter
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    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.

  7. #7
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  8. #8
    Fanatic Member
    Join Date
    Dec 2008
    Location
    St. John's, Newfoundland, Canada
    Posts
    965

    Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting

    Quote 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.

  9. #9
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: [VB] Number functions: High/Low Word/Byte, Swap Words/Bytes, Bitshifting

    Quote 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
  •  



Click Here to Expand Forum to Full Width