Results 1 to 8 of 8

Thread: [RESOLVED] Help with formula

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,462

    Resolved [RESOLVED] Help with formula

    I got this off the Net and it works... getting the size of 4 bytes in synchsafe format

    Code:
    Function CalcSize(ss) As Long
       
        Dim c As Long
        Dim d As Long
        Dim b As Long
        b = 2 ^ 21
        c = 2 ^ 14
        d = 2 ^ 7
        
       CalcSize = Asc(Mid(ss, 1, 1)) * b Or Asc(Mid(ss, 2, 1)) * c Or Asc(Mid(ss, 3, 1)) * d Or Asc(Mid(ss, 4, 1))
    End Function
    Can someone help me work out the reverse please ... get the 4 byte values from the number?

    Thanks

  2. #2
    PowerPoster
    Join Date
    Dec 2004
    Posts
    25,618

    Re: Help with formula

    i tested this and it returned the correct result
    Code:
    Function revv(f)
    Dim s As Long, t As Long, u As Long, v As Long
    s = (f \ 2 ^ 21)
    t = (f - s * 2 ^ 21) \ 2 ^ 14
    u = (f - s * 2 ^ 21 - t * 2 ^ 14) \ 2 ^ 7
    v = (f - s * 2 ^ 21 - t * 2 ^ 14 - u * 2 ^ 7)
    revv = Chr(s) & Chr(t) & Chr(u) & Chr(v)
    End Function
    it would probably be better to use more variables rather than as many recalculations

    edit: this version increased the speed, though on a single iteration i doubt it has any relevance

    Code:
    Function revv2(ByVal f)
    Dim s As Long, t As Long, u As Long, v As Long
    s = (f \ 2 ^ 21)
    f = f - s * 2 ^ 21
    t = f \ 2 ^ 14
    f = f - t * 2 ^ 14
    u = f \ 2 ^ 7
    v = f - u * 2 ^ 7
    
    revv2 = Chr(s) & Chr(t) & Chr(u) & Chr(v)
    End Function
    Last edited by westconn1; Feb 7th, 2018 at 04:13 AM.
    i do my best to test code works before i post it, but sometimes am unable to do so for some reason, and usually say so if this is the case.
    Note code snippets posted are just that and do not include error handling that is required in real world applications, but avoid On Error Resume Next

    dim all variables as required as often i have done so elsewhere in my code but only posted the relevant part

    come back and mark your original post as resolved if your problem is fixed
    pete

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,462

    Re: Help with formula

    Thank you Pete. Works spot on and way above my maths level!
    It'll be a huge help.
    Cheers

  4. #4
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Help with formula

    You're using variants quite a bit which are slower than a Typed variable. If you don't have a specific need for using variants, then you should avoid them.
    For instance, parameter ss is a variant, and the functions revv and revv2 parameters are variants and the functions returns a variant.

    You're using the variant form of the "string" functions, i.e. Mid and Chr rather than the string versions. The string versions will be faster than the variant versions.

    Also, the Asc function will return the ASCII code for the first character of a string, so it turns out if you're using Mid$ to pass a substring to Asc function it is quicker to drop the third parameter.

    Essentially what the code is doing is just taking 7-bit values, and shifting them by multiples of 7-bits to pack four of them into 28-bits of a 32-bit long. I think it would probably be faster when doing the unpacking to just mask out the 7-bit field you want and then "shift" that down to "right" justify it.

    So, doing what I described above, the two functions could look like this.
    Code:
    Function CalcSize(ss As String) As Long
      Const b As Long = 2 ^ 21
      Const c As Long = 2 ^ 14
      Const d As Long = 2 ^ 7
        
      CalcSize = Asc(Mid$(ss, 1)) * b Or Asc(Mid$(ss, 2)) * c Or Asc(Mid$(ss, 3)) * d Or Asc(Mid$(ss, 4))
    End Function
    
    Function revv3(ByVal f) As String
      Dim s As Long, t As Long, u As Long
    
      s = (f And &HFE00000) \ 2 ^ 21
      t = (f And &H1FC000) \ 2 ^ 14
      u = (f And &H3F80) \ 2 ^ 7
      revv3 = Chr$(s) & Chr$(t) & Chr$(u) & Chr$(f And &H7F)
    End Function
    Last edited by passel; Feb 8th, 2018 at 06:16 AM.

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,462

    Re: [RESOLVED] Help with formula

    Thanks for those refinements, Passel, I'll switch to using them. Some I knew and should have used but I'd focused on the showing the calculation which
    you've explained very nicely !

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: [RESOLVED] Help with formula

    Thanks.
    I was just looking back at Hex values of the masks, thinking how you should be able to see how the bit pattern is derivable from one to the next by seeing the value is a contiguous value of 7 bits and picks up where the previous one left off and it immediately jumped out at me this morning that the mask for variable s was wrong.
    s = (f And &HF700000) ...

    There are 7 bits set in the hex value F7, the four bits in the nibble F (a nibble is 1/2 a byte, i.e. 4-bits) and 3 bits in the nibble 7, but the three bits in 7 are the lower 3 bits, not the upper 3 bits of the nibble so the 7-bits set are not contiguous and span 8 bits instead of 7.

    And if you look at the Hex mask for t, you see it is hex 1F, so 1 is the lowest bit in that nibble and that overlaps with 7 which would be the lower 3 bits of the nibble. So, instead of 7 and 1, which overlap, it should be E and 1 which don't overlap.

    Therefore, the mask for s should have been &HFE00000, not &HF700000.
    Code:
      s = (f And &HFE00000) \ 2 ^ 21
    I'll correct post #4 in case someone comes across this thread and uses the code in post #4 without reading further down the thread.

  7. #7

    Thread Starter
    Frenzied Member
    Join Date
    Jun 2010
    Posts
    1,462

    Re: [RESOLVED] Help with formula

    Nice one Passel, I was still implementing/testing. Quite possibly would never have known as that's the high byte and out of range for most values But good to get it right !
    Thanks again

  8. #8
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: [RESOLVED] Help with formula

    Yeah. If I had written the four values in Hex in Notepad, or some other editor so I could keep them aligned, it would have been easier than doing it in my head.
    Code:
    &H00000000
    &H0000007F
    &H00003F80
    &H001FC000
    &H3FE00000
    Perhaps if I had just written 32 zeros in groups of 4 and copied it four times and then set the 7-bit fields of ones manually in the four lines it might have been a little easier to align the bits than writing the hex directly.
    Code:
    0000 0000 0000 0000 0000 0000 0000 0000 = 0
    0000 0000 0000 0000 0000 0000 0111 1111 = 0000007F
    0000 0000 0000 0000 0011 1111 1000 0000 = 00003F80
    0000 0000 0001 1111 1100 0000 0000 0000 = 001FC000
    0000 1111 1110 0000 0000 0000 0000 0000 = 0FE00000
    But, then again, I could just bring up a Visual Basic project in Visual Studio and go the immediate window and type in a string of 32 0's, then backover the last 7 and type seven 1's in and feed it to Convert.ToInt32 methods to convert binary string of digits to Int32 and then Convert.ToString to convert that Int32 into a Hex$.

    Then just hit the up arrow to repeat the line, but select the 7 zeros in front of the ones, Ctrl-X to cut them, and then paste them in after the ones to "shift" the seven ones up seven bits, and convert again. I think that is even quicker.
    Code:
    ? Convert.toString(Convert.toInt32("00000000000000000000000001111111",2),16)
    "7f"
    ? Convert.toString(Convert.toInt32("00000000000000000011111110000000",2),16)
    "3f80"
    ? Convert.toString(Convert.toInt32("00000000000111111100000000000000",2),16)
    "1fc000"
    ? Convert.toString(Convert.toInt32("00001111111000000000000000000000",2),16)
    "fe00000"
    Or could have used String.Format instead of Convert.ToString, but that is actually one character longer, e.g.
    Code:
    ? string.Format("{0:X}",Convert.ToInt32("0000000000000000000000001111111",2))
    "7F"
    Interestingly, the results are slightly different as String.Format capitalizes the hex digits.
    Last edited by passel; Feb 9th, 2018 at 03:31 AM.

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