For Programmers: Free Programming Magazines  


Home > Archive > Visual Basic > July 2006 > Raw type cast









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Raw type cast
magne

2006-07-01, 7:55 am

Using VB 6.0

I have a variable of type VT_I4 or Long.
Actually this variable is not an integer, but a IEEE single value, the
problem is just that it is not "given" to me as a Single.

I know I can make a form of "raw typecast" by declaring two user defined
types,
one which has an element of type Long, the other with element of type
Single, then performing a LSet which just copies bits.
Then my incoming VT_I4 or Long is fully "casted" to a Single.

Can this be done more "directly" (without occupying extra memory) ?
Can two variables (different types) refer to the same memory location ?


MikeD

2006-07-01, 7:55 am


"magne" <magne@nospam.nospam> wrote in message
news:OvmXSaPnGHA.1208@TK2MSFTNGP04.phx.gbl...
> Using VB 6.0
>
> I have a variable of type VT_I4 or Long.
> Actually this variable is not an integer, but a IEEE single value, the
> problem is just that it is not "given" to me as a Single.
>


That doesn't make much sense to me but maybe because I'm not familiar with a
VT_I4 type.

> I know I can make a form of "raw typecast" by declaring two user defined
> types,
> one which has an element of type Long, the other with element of type
> Single, then performing a LSet which just copies bits.
> Then my incoming VT_I4 or Long is fully "casted" to a Single.
>
> Can this be done more "directly" (without occupying extra memory) ?


I've no idea since I don't really understand the underlying problem.

> Can two variables (different types) refer to the same memory location ?



No to my knowledge with one sort-of exception, which would be passing a
parameter to a procedure ByRef. The parameter in the called procedure has
the same memory address as the passed variable in the calling procedure. I
don't know how that could help you though.

--
Mike
Microsoft MVP Visual Basic

Mike Williams

2006-07-01, 7:55 am

"magne" <magne@nospam.nospam> wrote in message
news:OvmXSaPnGHA.1208@TK2MSFTNGP04.phx.gbl...

> Using VB 6.0. I know I can make a form of "raw typecast" by declaring two
> user defined types, one which has an element of
> type Long, the other with element of type Single, then performing
> a LSet which just copies bits. Then my incoming VT_I4 or Long
> is fully "casted" to a Single.


Don't know what you mean by VT_I4, but you can certainly do that with a
Long. Or you could instead use CopyMemory.

> Can this be done more "directly" (without occupying extra
> memory) ? Can two variables (different types) refer to the
> same memory location ?


Yes, but for such a small task you'll be saving only a tiny amount of memory
and gaining very little speed, unless of course you're dealing with lots of
them. Have a look at the SafeArray structure. It is a technique that is most
often used for creating an array structure that allows you to deal with a
String or a block of bitmap data as though it was an array of bytes or longs
or integers or whatever, but it will also do the job you have in mind. In
fact we've just been talking about SafeArray in the thread entitled "Number
of occurances" (sic) and if you have a look in that thread at the first of
my responses dated 1 July and at RB Smissaert's three follow up responses
you'll see an example.

Mike


Jim Mack

2006-07-01, 7:55 am

magne wrote:
> Using VB 6.0
>=20
> I have a variable of type VT_I4 or Long.
> Actually this variable is not an integer, but a IEEE single value, the
> problem is just that it is not "given" to me as a Single.


This seems like something you can cure with just a proper Declare. How =
is this "given" to you?


> Can two variables (different types) refer to the same memory location?


Not in pure VB. The closest you can come is a Variant.

If it's possible to get your value into a variant, then you can change =
the type of the variant with a little bit twiddling. But this isn't much =
of a solution since a variant will occupy more memory that a single and =
a long combined.

--=20

Jim Mack
MicroDexterity Inc
www.microdexterity.com
Ralph

2006-07-01, 7:55 am


"magne" <magne@nospam.nospam> wrote in message
news:OvmXSaPnGHA.1208@TK2MSFTNGP04.phx.gbl...
> Using VB 6.0
>
> I have a variable of type VT_I4 or Long.
> Actually this variable is not an integer, but a IEEE single value, the
> problem is just that it is not "given" to me as a Single.
>
> I know I can make a form of "raw typecast" by declaring two user defined
> types,
> one which has an element of type Long, the other with element of type
> Single, then performing a LSet which just copies bits.
> Then my incoming VT_I4 or Long is fully "casted" to a Single.
>
> Can this be done more "directly" (without occupying extra memory) ?
> Can two variables (different types) refer to the same memory location ?
>


This doesn't make any sense.
A VT_I4 is a Variant data type := long (long integer). A "single" (VT_R4)
would have a very different bit lay out stuffed into 4 bytes.

Are you sure you aren't just dealing with a Com Variant animal and making it
overly complicated? Just use CSng(ThisAnimal) and CLng(ThisAnimal) as
required.

-ralph


Larry Serflaten

2006-07-01, 6:55 pm


"MikeD" <nobody@nowhere.edu> wrote

[color=darkred]
> I've no idea since I don't really understand the underlying problem.


It might have been possible to have done that, something like:

Private Type MyData
Bytes(0 to 3) as Byte
End Type

Private Union MyData
Value As Long
End Union

Dim data As MyData

data.Value = &H55555555&
Debug.Print data.Bytes(0), data.Bytes(1), ...

Where, because data is 'unioned' the members of both types
access the same memory, just in a different fashion.

FWIW, there is an API routine VariantChangeType that may be
one solution to the problem, but as usual, MSDN lists it without
thought of the VB developer....

http://msdn2.microsoft.com/en-us/library/ms221258.aspx

With that, the type might be changed 'in place' with no data
copying needed.

LFS


magne

2006-07-01, 6:55 pm

Thanks all of you, the problem is due to a limitation of a communication
protocol (MODBUS from Modicon), which only allows integers (16 bits) to be
transferred.
The sender side cuts a 32 bits real in two parts and sends these halves as
16 bit integers, my problem is to recompile to a real.
Recompiling to a Long is no problem, from there to Single is the problem...

"Ralph" <nt_consulting64@yahoo.com> wrote in message
news:w6OdnXvLC5en5zvZnZ2dnUVZ_tydnZ2d@ar
kansas.net...
>
> "magne" <magne@nospam.nospam> wrote in message
> news:OvmXSaPnGHA.1208@TK2MSFTNGP04.phx.gbl...
>
> This doesn't make any sense.
> A VT_I4 is a Variant data type := long (long integer). A "single" (VT_R4)
> would have a very different bit lay out stuffed into 4 bytes.
>
> Are you sure you aren't just dealing with a Com Variant animal and making
> it
> overly complicated? Just use CSng(ThisAnimal) and CLng(ThisAnimal) as
> required.
>
> -ralph
>
>



Jim Mack

2006-07-01, 6:55 pm

Larry Serflaten wrote:
=20
>=20
> FWIW, there is an API routine VariantChangeType that may be
> one solution to the problem, but as usual, MSDN lists it without
> thought of the VB developer....


I'm pretty sure this will perform a "CSng()" or whatever conversion is =
asked for. It doesn't change the meaning of the bits "in place", it =
changes the value from one type to another.

It is possible to change the bits in place, but it requires changing the =
value of a field in the variant (using CopyMem).

--=20
Jim
Larry Serflaten

2006-07-01, 6:55 pm


"Jim Mack" <jmack@mdxi.nospam.com> wrote
>
> FWIW, there is an API routine VariantChangeType that may be
> one solution to the problem, but as usual, MSDN lists it without
> thought of the VB developer....


> I'm pretty sure this will perform a "CSng()" or whatever conversion is asked for.
> It doesn't change the meaning of the bits "in place", it changes the value from one type to another.


> It is possible to change the bits in place, but it requires changing the value of a field in the variant (using CopyMem).


Aha! (who would have guessed a function named 'Change', really means
'Convert' ...) <g>

Something like this then...

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal length As Long)

Private Sub Form_Load()
Dim v

v = CLng(1234)
Debug.Print TypeName(v), v
CopyMemory v, 4, 2
Debug.Print TypeName(v), v

End Sub


LFS



Jim Mack

2006-07-01, 9:55 pm

Larry Serflaten wrote:
>=20
> Something like this then...
>=20
> Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
> (Destination As Any, Source As Any, ByVal length As Long)
>=20
> Private Sub Form_Load()
> Dim v
>=20
> v =3D CLng(1234)
> Debug.Print TypeName(v), v
> CopyMemory v, 4, 2
> Debug.Print TypeName(v), v
>=20
> End Sub



Yep, though I would have done "CopyMemory v, VT_R4, 2" for clarity. =
Though now that I say it, the VT_ constants might not be available in =
VB.

Keep in mind that not every bit pattern is legal as a Single. You should =
do this only for values that are known to be singles masquerading as =
Longs, etc, or risk a floating point exception.

--=20
Jim
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com