Converting IEEE Format Singles To Internal Longs
-
Does anyone know if VB can now (VB6.0) perform a conversion between the internal representation of a single-precision number (held as a long, 4 bytes) and an actual Single? By this I mean, the value 1.0 as a Single = &h3F800000 internally. If I have a Long containing &h3F800000, is it possible to convert to a Single of 1.0, and vice versa (Single -> Long holding internal representation). So far I have had to use a C DLL to do this. Other possible ways to do this might involve using Variants, Byte arrays or some way of accessing the memory used to store the variables (used to be VARSEG and VAROFFSET in QuickBasic) - but I can't find a way. Note that CLng(Single) and CSng(Long) don't do it, since CSng(&h3F800000) = 1065353216.0, which isn't quite 1.0 {:v) Note also that you can't use Any as the type in your own functions {:v( If anyone's wondering why I need this, it's to pull bytes out of a Modbus message and decode them, or to encode them and plug them into a message.
-
Does anyone know if VB can now (VB6.0) perform a conversion between the internal representation of a single-precision number (held as a long, 4 bytes) and an actual Single? By this I mean, the value 1.0 as a Single = &h3F800000 internally. If I have a Long containing &h3F800000, is it possible to convert to a Single of 1.0, and vice versa (Single -> Long holding internal representation). So far I have had to use a C DLL to do this. Other possible ways to do this might involve using Variants, Byte arrays or some way of accessing the memory used to store the variables (used to be VARSEG and VAROFFSET in QuickBasic) - but I can't find a way. Note that CLng(Single) and CSng(Long) don't do it, since CSng(&h3F800000) = 1065353216.0, which isn't quite 1.0 {:v) Note also that you can't use Any as the type in your own functions {:v( If anyone's wondering why I need this, it's to pull bytes out of a Modbus message and decode them, or to encode them and plug them into a message.
I haven't tested it, but this should work:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Public Function Long2Sng(ByVal InVal As Long) As Single
Dim sRet As Single
CopyMemory sRet, InVal, 4
Long2Sng = sRet
End Function -
I haven't tested it, but this should work:
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Public Function Long2Sng(ByVal InVal As Long) As Single
Dim sRet As Single
CopyMemory sRet, InVal, 4
Long2Sng = sRet
End FunctionI can confirm that it does indeed work - no more C DLLs - hurrah! ;P