Results 1 to 16 of 16

Thread: Math Issue - Long to WORD converstion problem

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Oct 2005
    Location
    Earth
    Posts
    16

    Math Issue - Long to WORD converstion problem

    I need to take a long value, which ranges between 0~32768, and convert it into a WORD.

    I've dimmed two BYTE data types:
    Dim Hbyte As Byte
    Dim Lbyte As Byte


    What is the easiest way to convert the long value into these two bytes? The most painful way is:

    TempLONG holds a value ranging between 0 ~ 32768

    If TempLONG > 32767 Then TempLONG = TempLONG - 32768: Hbyte = Hbyte + 128
    If TempLONG > 16383 Then TempLONG = TempLONG - 16384: Hbyte = Hbyte + 64
    If TempLONG > 8191 Then TempLONG = TempLONG - 8192: Hbyte = Hbyte + 32
    If TempLONG > 4095 Then TempLONG = TempLONG - 4096: Hbyte = Hbyte + 16
    If TempLONG > 2047 Then TempLONG = TempLONG - 2048: Hbyte = Hbyte + 8
    If TempLONG > 1023 Then TempLONG = TempLONG - 1024: Hbyte = Hbyte + 4
    If TempLONG > 511 Then TempLONG = TempLONG - 512: Hbyte = Hbyte + 2
    If TempLONG > 255 Then TempLONG = TempLONG - 256: Hbyte = Hbyte + 1
    LByte = TempLONG

    The above routine works, but come on...

    Any ideas?


    0x34

  2. #2
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Math Issue - Long to WORD converstion problem

    Since your range only goes to 32768
    Code:
    If TempLong = 32768 Then rtnInteger = -TempLong Else rtnInteger = TempLong
    If you are trying to separate the value into 2 bytes:
    Code:
    LowByte = TempLong And &HFF
    HighByte = (TempLong And &HFF00) \ &H100
    Last edited by LaVolpe; Feb 26th, 2015 at 12:37 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Oct 2005
    Location
    Earth
    Posts
    16

    Re: Math Issue - Long to WORD converstion problem

    Of course... Sometimes the brain is on vacation...

    This works perfectly:
    LowByte = TempLong And &HFF
    HighByte = (TempLong And &HFF00) \ &H100

    Thanks LaVolpe!

    0x34

  4. #4
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Math Issue - Long to WORD converstion problem

    Or even:

    Code:
        Dim TempLong As Long
        Dim LowByte As Byte
        Dim HighByte As Byte
    
        TempLong = 32768
        LowByte = TempLong And &HFF
        HighByte = TempLong \ &H100
    As "long" (sorry, bad pun) as you do not exceed 65535 you do not need the extra masking operation.

  5. #5
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Math Issue - Long to WORD converstion problem

    Quote Originally Posted by dilettante View Post
    As "long" (sorry, bad pun) as you do not exceed 65535 you do not need the extra masking operation.
    Very true, just felt better safe than sorry, but could've offered both options
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: Math Issue - Long to WORD converstion problem

    Just spelling it out. Future readers and all that.

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Oct 2005
    Location
    Earth
    Posts
    16

    Re: Math Issue - Long to WORD converstion problem

    Since I have you guy's attention, I'll pose one more question.

    This routine is part of an audio streaming function, which needs to operate as fast as possible. Looking at the following subroutine, can you see a way to make it work faster?
    Code:
    Private Sub HandleStreamBuffer(bSize As Long) ' Converts LONG into a two byte word
    Dim T As Integer
    Dim lPTR As Long
    Dim Hbyte As Byte
    Dim Lbyte As Byte
    On Error GoTo Error
        lPTR = 0
        Hbyte = 0: Lbyte = 0
        ReDim MyBytes(0 To 4095) As Byte
        For T = 0 To 2047
            Lbyte = (32767 + CLng(UDPBuffer(T))) And &HFF
            Hbyte = (32767 + CLng(UDPBuffer(T))) \ &H100
            MyBytes(lPTR) = Hbyte
            MyBytes(lPTR + 1) = Lbyte
            lPTR = lPTR + 2
            Hbyte = 0: Lbyte = 0
        Next
    Exit Sub
    Error:
        Debug.Print "ERROR: " & err.Number & " - " & Error$(err.Number)
    End Sub

    0x34

  8. #8
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: Math Issue - Long to WORD converstion problem

    Use RtlMoveMemory. For very-very fast work you can to use SIMD-extensions (MMX, SSE etc.), but need to known how its made, and know assembler. For example - addition (mixing) two arrays with saturation (If result > MaxTypeValue Then result = MaxTypeValue, also for negative numbers) use MMX:
    Code:
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal ptrFc As Long, ByVal P1 As Long, ByVal P2 As Long, ByVal P3 As Long, ByVal P4 As Long) As Long
    Private Code() As Byte
    Private Function HexToBin(Data As String) As Long
        Dim i As Long
        ReDim Code(Len(Data) \ 2 - 1)
        For i = 0 To UBound(Code)
            Code(i) = CByte("&H" & Mid(Data, i * 2 + 1, 2))
        Next i
        HexToBin = VarPtr(Code(0))
    End Function
    Private Sub MixArray()
        Dim Src() As Byte                       ' Первый массив
        Dim Shp() As Byte                       ' Второй массив
        Dim Count As Long, Asm As Long          ' Число итераций, адрес функции
        Dim X1 As Single, X2 As Single, N As Long
        ' Размер массива должен быть кратен 8
        ' В переменной Count содержится число итераций сложения (1 итерация - 8 байт)
        ReDim Src(65535): ReDim Shp(65535)
        X1 = (6.28 / UBound(Src)) * 10           ' 10 волн синусоиды
        X2 = (6.28 / UBound(Shp)) * 7            ' 7 волн синусоиды
        For N = 0 To UBound(Src): Src(N) = Sin(X1 * N) * 127 + 128: Shp(N) = Sin(X2 * N) * 127 + 128: Next N
        ' Count= LenghtBytes\8
        Count = (UBound(Src) + 1) \ 8
        Asm = HexToBin("5589E55356578B75088B7D0C8B4D100F770F6F070F6F0E0FDCC80F7F0E83C60883C708E2EC0F775F5E5B89EC5DC3")
        CallWindowProc Asm, VarPtr(Src(0)), VarPtr(Shp(0)), Count, 0
    End Sub
    Private Sub Form_Load()
        MixArray
    End Sub

  9. #9
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Math Issue - Long to WORD converstion problem

    To speed up your array:

    1) Cache calculations within a loop if going to be used more than once and then use the cached value
    2) Remove unnecessary assignments, i..e, no point in resetting values to zero if they will be immediately reassigned new values
    Code:
    Dim lngNew As Long
    ...
    
    For T = 0 To 2047
        lngNew = 32767& + CLng(UDPBuffer(T))
        MyBytes(lPTR + 1) = lngNew And &HFF
        MyBytes(lPTR) =lngNew \ &H100
        lPtr = lPtr + 2
    Next
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  10. #10

  11. #11

    Thread Starter
    Junior Member
    Join Date
    Oct 2005
    Location
    Earth
    Posts
    16

    Thumbs up Re: Math Issue - Long to WORD converstion problem

    Thanks for the help gentlemen. It works nicely!

    0x34

  12. #12

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Math Issue - Long to WORD converstion problem

    Quote Originally Posted by The trick View Post
    By the way, VB6 itself simplifies expressions and avoids code duplication in expressions also eliminates unused variables which do not have any use, as well as any action with them.
    Regarding unused variables, if I recall correctly, that only applies at the module level, not in private methods/properties. But when compiled, yes, VB does try to optimize our code.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: Math Issue - Long to WORD converstion problem

    Lot of cases when VB6 delete a unused variable. For example procedure-level variables.
    Code:
    Option Explicit
     
    Private Declare Function GetMem4 Lib "msvbvm60" (Src As Any, Dst As Any) As Long
     
    Dim cx      As Currency
     
    Public Function Test() As Long
        Static ok   As Long
        Dim inIde   As Boolean          ' Necessary condition - a variable level procedures
     
        Debug.Assert MakeTrue(inIde)
            
        If inIde Then
            ' This code does not get into compiled file with the test
            ' as if the If statement is not present, compiles only branch Else
            ' We use it to bypass overflow
            cx = 0@
            GetMem4 ok, cx
            cx = cx * 137687 + 12.3467@
            GetMem4 cx, ok
            
        Else
            ' Only the code gets to EXE
            ok = ok * 137687 + 123467
            
        End If
         
        Test = ok
        
    End Function
     
    Private Function MakeTrue(value As Boolean) As Boolean
        MakeTrue = True
        value = True
    End Function

  15. #15
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Math Issue - Long to WORD converstion problem

    Per MSDN
    Although Visual Basic does remove unused constants, it does not remove unused variables and dead code when you create an .exe. Consider reviewing your code to find and remove unused procedures and variables. For example, Debug.Print statements, while ignored in the run-time .exe, are sometimes present in the .exe file.
    Regarding your example above, I don't have a decompiler to verify what you say is true. But if you change the line to read "If Not inIde Then", are you saying your msgbox would be the same result?

    Edited: Trick+ ...
    Think I see what you are saying, but not sure if 'unused' code lines are being ignored or optimized compilation is the reason. For example. If I leave your code 'as-is' and insert 100 lines of: For ok = 0 to 100: cx = cx + ok: Next, then the exe file size after compiling with the extra code does not grow. However, If I insert in the same place, DIM statements of 100 different variables, then the file size grows after compiled. Personally, instead of trying to determine what will or will not be compiled, think I'll just agree to Microsoft's recommendation & remove unused variables and dead code.
    Last edited by LaVolpe; Feb 26th, 2015 at 03:48 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  16. #16
    PowerPoster
    Join Date
    Feb 2015
    Posts
    2,797

    Re: Math Issue - Long to WORD converstion problem

    Quote Originally Posted by LaVolpe View Post
    Regarding your example above, I don't have a decompiler to verify what you say is true. But if you change the line to read "If Not inIde Then", are you saying your msgbox would be the same result?
    If inIde Then (compiled only Else branch):

    If Not inIde Then (compiled only True branch):

    Code:
    Public Function Test() As Long
        Static ok   As Long
        Dim inIde   As Boolean          ' Обязательное условие - переменная уровня процедуры
        Dim a       As Long
        Dim b       As Long
        Dim c       As Long
        Dim j       As Single
        Dim l       As Single
        
        Debug.Assert MakeTrue(inIde)
            
        If inIde Then
            ' Этот код вообще не попадет в скомпилированный файл вместе с проверкой
            ' как-будто инструкции If нет, скомпилируется только ветка Else
            ' Это мы используем для обхода ошибки переполнения
            cx = 0@
            GetMem4 ok, cx
            cx = cx * 137687 + 12.3467@
            GetMem4 cx, ok
            
        Else
            ' Только этот код попадет в EXE
            ok = ok * 137687 + 123467
            
        End If
         
        Test = ok
        
    End Function
    same.

    Variant, Array, String, Object - not optimize.
    Quote Originally Posted by LaVolpe View Post
    Per MSDN
    In MSDN and support there are errors. For instance generation algorithm RND is not true.

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