|
-
Sep 13th, 2001, 11:00 PM
#1
Thread Starter
Fanatic Member
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?
-
Sep 13th, 2001, 11:58 PM
#2
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
-
Sep 14th, 2001, 12:44 AM
#3
Registered User
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.
-
Sep 14th, 2001, 02:39 AM
#4
transcendental analytic
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.
-
Sep 14th, 2001, 07:36 AM
#5
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.
-
Sep 14th, 2001, 07:43 AM
#6
transcendental analytic
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.
-
Sep 14th, 2001, 07:47 AM
#7
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?
-
Sep 14th, 2001, 07:54 AM
#8
transcendental analytic
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.
-
Sep 14th, 2001, 03:37 PM
#9
Addicted Member
Can't you just do something like:
VB Code:
lowerBytes= number mod (2^(8*3))
upperBytes= int( number / (2^(8*3)) )
-
Sep 14th, 2001, 04:51 PM
#10
transcendental analytic
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.
-
Sep 17th, 2001, 10:48 PM
#11
Registered User
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:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Sub Command1_Click()
Dim c As Currency
Dim c2 As Currency
Dim l As Long
Dim i&
c = 25286201964530#
Debug.Print c
CopyMemory ByVal VarPtr(c2) + 2, ByVal VarPtr(c) + 2, 6
Debug.Print c2
End Sub
This works (obviously)
Code:
c = 25286201964530#
Debug.Print c
CopyMemory ByVal VarPtr(c2), ByVal VarPtr(c), 8
Debug.Print c2
-
Sep 18th, 2001, 12:40 AM
#12
Registered User
You can do it with decimal though:
VB Code:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Sub Command1_Click()
Dim d As Variant
Dim lHigh As Long
Dim lLow As Long
d = CDec(25286201964530#)
CopyMemory ByVal VarPtr(lHigh), ByVal VarPtr(d) + 11, 3
CopyMemory ByVal VarPtr(lLow), ByVal VarPtr(d) + 8, 3
Debug.Print Hex(lLow), Hex(lHigh)
End Sub
-
Sep 18th, 2001, 02:41 AM
#13
Fanatic Member
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 
-
Sep 18th, 2001, 03:19 AM
#14
Registered User
Originally posted by Kaverin
Heh heh. Moving along to Sephiroth now .
That should be confusing most people by now
-
Sep 18th, 2001, 05:01 AM
#15
transcendental analytic
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|