Results 1 to 15 of 15

Thread: Singles

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Oct 2000
    Location
    Oregon
    Posts
    962

    Singles

    Anyone know how to split a single into 3 byte longs?

    basicly, I want to pass in 16FF6715F7F2 and get 16FF67 and 15F7F2 out.

    Yes , I know longs are 4 bytes in VB, but the rotines I am using require 3 bytes. By the way, how many bytes long is the longest possible single?

  2. #2
    Aurilus
    Guest
    OK.. I think this should do the trick for you It won't store them as 3-byte longs but will instead split it up into four-byte longs, which you can then change to 3-byte longs from there.

    Code:
        Dim V1 As Long, V2 As Long
        SplitValue &H123456, V1, V2
        MsgBox Hex(&H123456) & vbNewLine & Hex(V1) & " " & Hex(V2)
    
    Public Sub SplitValue(ByVal ValueIn As Single, ByRef BigValue As Long, ByRef SmallValue As Long)
        Dim ChunkSize As Long
        ' &H10 = split into 1-digit chunks
        ' &H100 = split into two digit chunks
        ' &H1000 = split into three digit chunks
        ' &H10000 = split into four digit chunks
        ' &H100000 = split into five-digit chunks
            ChunkSize = &H1000
        
        BigValue = ValueIn \ ChunkSize
        SmallValue = ValueIn - (BigValue * ChunkSize)
    End Sub
    Sorry 'bout the quality of the code, but at least it works

    All you have to do is change the ChunkSize value to split up how many bytes you want it cut into.

    - Aurilus

  3. #3
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    Create a byte array to hold the data size it to hold 4 bytes. then use copymemory to copy the data into the byte array.

    So all you do is pass the pointer to the variable and a pointer to the 1st element of the byte array using varptr() and let copymemory api do all the work for you.

    Then you can loop through the byte array to examine each byte.

  4. #4
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Single is a IEEE Standard 754 Floating Point precision datatype, it will contain unusable information as raw memory for you, have a look at:
    http://research.microsoft.com/~holla...ieeefloat.html

    16FF6715F7F2 is 25286201964530 decimal, would be stored 2.52862E+13 in a single; 25286200000000. You should rather use a Currency 64 bit integer or decimal datatype, the latter if you don't want to mess with the decimal point shift, the earlier if you want to save speed. Then you can copymemory the 3 hi bytes from currency to long.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  5. #5
    DerFarm
    Guest
    Well, being totally out of my element here, I'm taking a crack at
    this.

    I was working on decoding packed data, which works with the
    upper 4 bits and lower 4 bits of a character. Essentially, I found
    that

    (CH AND 240)/8 = Upper Nibble in Lower Nibble format
    (CH and 15) = Lower Nibble in Lower Nibble format

    It would seem that you could do something similar for the 4
    bytes, using words instead of nibbles.


    Be a damn sight faster than arraying a series of 0 and 1 constructs.

  6. #6
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    Actually not worth a try unless you do it in assmbler on a cpu that can handle 64 bit integers. Copymemory will do fine, btw
    do
    CH \ 16
    instead of
    (CH AND 240)/8 to get the hi nibble, \ stands for integer division.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  7. #7
    DerFarm
    Guest
    hmmmmmmm......Good idea. Actually, now that I think of it, your
    copy memory would work perfectly. I'm getting too used to
    thinking in VB.

    Simply read the bit patterns from a part of one location to the
    lower bits of another (zeroed) position. Then read the 2nd
    position as a long.

    Is this what you meant?

  8. #8
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    well eh, you make it sound weird, actually it is this simple:
    you start at the 6'th byte on currency and copy to 2nd on the long
    Currency:
    [00 00 16 FF 67 *15 F7 F2* ]
    Long:
    [00 *15 F7 F2*]
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  9. #9
    Addicted Member Dim A's Avatar
    Join Date
    Jul 2000
    Posts
    201
    Can't you just do something like:
    VB Code:
    1. lowerBytes= number mod (2^(8*3))
    2. upperBytes= int(  number / (2^(8*3))  )

  10. #10
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    modulus can't be emulated on 64 bit integer in vb, even if it would, copymemory would be faster, if you coded in assembly on a 64 bit cpu you would rather use bitwise and than modulus

    and also, evulate all the numeric expressions, since vb's compiler isn't smart enough to do that itself
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  11. #11
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    Originally posted by kedaman
    well eh, you make it sound weird, actually it is this simple:
    you start at the 6'th byte on currency and copy to 2nd on the long
    Currency:
    [00 00 16 FF 67 *15 F7 F2* ]
    Long:
    [00 *15 F7 F2*]
    Are you sure currency stores it that way?

    I found I had to move all 8 bytes to copy the value from one currency to the other?

    This fails:
    VB Code:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    2.  
    3. Private Sub Command1_Click()
    4. Dim c As Currency
    5. Dim c2 As Currency
    6. Dim l As Long
    7. Dim i&
    8.  
    9. c = 25286201964530#
    10. Debug.Print c
    11. CopyMemory ByVal VarPtr(c2) + 2, ByVal VarPtr(c) + 2, 6
    12. Debug.Print c2
    13. End Sub

    This works (obviously)
    Code:
    c = 25286201964530#
    Debug.Print c
    CopyMemory ByVal VarPtr(c2), ByVal VarPtr(c), 8
    Debug.Print c2

  12. #12
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    You can do it with decimal though:

    VB Code:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    2.  
    3. Private Sub Command1_Click()
    4.  Dim d As Variant
    5.  Dim lHigh As Long
    6.  Dim lLow As Long
    7.  
    8.  d = CDec(25286201964530#)
    9.  
    10.  CopyMemory ByVal VarPtr(lHigh), ByVal VarPtr(d) + 11, 3
    11.  CopyMemory ByVal VarPtr(lLow), ByVal VarPtr(d) + 8, 3
    12.  
    13.  Debug.Print Hex(lLow), Hex(lHigh)
    14.  
    15. End Sub

  13. #13
    Fanatic Member Kaverin's Avatar
    Join Date
    Oct 2000
    Posts
    930
    Heh heh. Moving along to Sephiroth now .
    I'm baaaack...
    VB5 Professional Edition, VC++ 6
    Using a 1 gHz Thunderbird, 256 mb RAM, 40 gb HD system with Win98se

    I feel special because I finally figured out how to loop midis: Post link
    I'm a fanatic too

  14. #14
    Registered User Nucleus's Avatar
    Join Date
    Apr 2001
    Location
    So that's what you are up to ;)
    Posts
    2,530
    Originally posted by Kaverin
    Heh heh. Moving along to Sephiroth now .
    That should be confusing most people by now

  15. #15
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221

    Smile Counterintuitive

    Heya Nucleus, you're correct, Currency is an oddball, the bytes are reversed while the bits within each byte is in same order.

    Code:
    Dim c As Currency
    Dim l As Long
    c = 0.0011
    Debug.Print c
    CopyMemory ByVal VarPtr(c2), ByVal VarPtr(l) + 3, 1
    Debug.Print l
    I guess M$ has a really good reason to do so, the emulation of Currency operations isn't done at cpu level, so in VB you could pretty much go any way you want.

    What you do now, is copy each byte separately
    C:0 -> L:3
    C:1 -> L:2
    C:2 -> L:1

    C=Currency L=Long :X = offset
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

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