Re: Little\Big-Endian Single and Double values
From: Francesco Ranieri (Francesco.Ranieri_at_eng.it)
Date: 11/18/04
- Next message: Dave: "Re: String patterns. How to ?"
- Previous message: J French: "Re: VB component works correctly only in debug mode"
- In reply to: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Next in thread: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Reply: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 18 Nov 2004 10:52:16 +0100
Thanks Mike... your suggestion helps always very much!
I've seen your code and it seems to me that you flip, simply, all bytes.
I see you're very skilled and I wish you examine this code in order to receive an your advice about:
'----------------------------- START CODE =>
'Structure of 64 bits
Public Type recUD64Bit
lngLowByte As Long
lngHighByte As Long
End Type
'APIs declarations
Public Declare Function HToNInt16 Lib "ws2_32.dll" Alias "htons" (ByVal intPRMHostValue As Integer) As Integer
Public Declare Function NToHInt16 Lib "ws2_32.dll" Alias "ntohs" (ByVal lngPRMNetValue As Long) As Integer
Public Declare Function HToNInt32 Lib "ws2_32.dll" Alias "htonl" (ByVal lngPRMHostValue As Long) As Long
Public Declare Function NToHInt32 Lib "ws2_32.dll" Alias "ntohl" (ByVal lngPRMNetValue As Long) As Long
'The my thinking....
Public Function HToNFloat32(ByVal sngPRMHostValue As Single) As Single
Dim lngTemp As Long
'Cast the float-32 into int-32
Call CopyMemory(lngTemp, sngPRMHostValue, 4)
'Convert int-32 in Big-Endian
lngTemp = HToNInt32(lngTemp)
'Cast the int-32 into float-32
Call CopyMemory(sngPRMHostValue, lngTemp, 4)
'Return the value
HToNFloat32 = sngPRMHostValue
End Function
Public Function NToHFloat32(ByVal sngPRMNetValue As Single) As Single
NToHFloat32 = HToNFloat32(sngPRMNetValue)
End Function
Public Function HToNFloat64(ByVal dblPRMHostValue As Double) As Double
Dim lngTemp As Long
Dim recTemp As recUD64Bit
'Background: Big\Little-Endian notation
'Position Little-Endian Big-Endian
'| Byte 1 | -> |Bit08 Bit01| -> |Bit64 Bit57|
'| Byte 2 | -> |Bit16 Bit09| -> |Bit56 Bit49|
'| Byte 3 | -> |Bit24 Bit17| -> |Bit48 Bit41|
'| Byte 4 | -> |Bit32 Bit25| -> |Bit40 Bit33|
'| Byte 5 | -> |Bit40 Bit33| -> |Bit32 Bit25|
'| Byte 6 | -> |Bit48 Bit41| -> |Bit24 Bit17|
'| Byte 7 | -> |Bit56 Bit49| -> |Bit16 Bit09|
'| Byte 8 | -> |Bit64 Bit57| -> |Bit08 Bit01|
'Cast the 8 bytes of the Little-Endian double into 8 bytes of the structure
Call CopyMemory(ByVal recTemp, dblPRMHostValue, 8)
With recTemp
'Swaps the first 4 bytes with the last 4 bytes
lngTemp = .lngHighByte
.lngHighByte = .lngLowByte
.lngLowByte = lngTemp
'Now, swapped the two longs amongst themselves, the situation is:
'Position Bits
'| Byte 1 | -> |Bit40 Bit33|
'| Byte 2 | -> |Bit48 Bit41| 'In .lngLowByte
'| Byte 3 | -> |Bit56 Bit49|
'| Byte 4 | -> |Bit64 Bit57|
'| Byte 5 | -> |Bit08 Bit01|
'| Byte 6 | -> |Bit16 Bit09| 'In .lngHighByte
'| Byte 7 | -> |Bit24 Bit17|
'| Byte 8 | -> |Bit32 Bit25|
'Flips the two DWords
.lngLowByte = HToNInt32(.lngLowByte)
.lngHighByte = HToNInt32(.lngHighByte)
'Now, flipped the two DWords, the situation is:
'Position Bits
'| Byte 1 | -> |Bit64 Bit57|
'| Byte 2 | -> |Bit56 Bit49| 'In .lngLowByte
'| Byte 3 | -> |Bit48 Bit41|
'| Byte 4 | -> |Bit40 Bit33|
'| Byte 5 | -> |Bit32 Bit25|
'| Byte 6 | -> |Bit24 Bit17| 'In .lngHighByte
'| Byte 7 | -> |Bit16 Bit09|
'| Byte 8 | -> |Bit08 Bit01|
End With
'Recreates the Big-Endian double
Call CopyMemory(dblPRMHostValue, ByVal VarPtr(recTemp), 8)
'Return the value in Big-Endian notation
HToNFloat64 = dblPRMHostValue
End Function
Public Function NToHFloat64(ByVal dblPRMNetValue As Double) As Double
NToHFloat64 = HToNFloat64(dblPRMNetValue)
End Function
'----------------------------- END CODE <=
This code should be perform the same operations of yours... without loops!
I've tryed to execute your code and mine... the result are the same!
Do you think I'm right and...."important" for me.... my code (without loop...) could be slightly faster than your approach (...with loop)??????
Thanks....
Francesco
P.S.
It seems to me that FlipBytes function executes the same operation of NToH\HToNL.. isn't it really?
I've found, also, your code to substitute the NToH\HToNL functions in an older post:
'----------------------------- START CODE =>Private Function SwapEndian(ByVal dw As Long) As Long
' by Mike D Sutton, Mike.Sutton@btclick.com, 20040914
SwapEndian = (((dw And &HFF000000) \ &H1000000) And &HFF&) Or _
((dw And &HFF0000) \ &H100&) Or _
((dw And &HFF00&) * &H100&) Or _
((dw And &H7F&) * &H1000000)
If (dw And &H80&) Then SwapEndian = SwapEndian Or &H80000000
End Function
'----------------------------- END CODE <=or, the variant (...by Bob O' Bob...), slightly faster:'----------------------------- START CODE =>Private Function FlipDWord(ByVal inDWord As Long) As Long If (inDWord And &H80&) Then FlipDWord = &H80000000 Or _ (((inDWord And &HFF000000) \ &H1000000) And &HFF&) Or _ ((inDWord And &HFF0000) \ &H100&) Or _ ((inDWord And &HFF00&) * &H100&) Or _ ((inDWord And &H7F&) * &H1000000) Else FlipDWord = (((inDWord And &HFF000000) \ &H1000000) And &HFF&) Or _ ((inDWord And &HFF0000) \ &H100&) Or _ ((inDWord And &HFF00&) * &H100&) Or _ ((inDWord And &H7F&) * &H1000000) End IfEnd Function'----------------------------- END CODE <=
and, Donald Lessau has discovered that your code is faster than others approaches and... some more than NToH\HToNL functions!!!!!
I think that I'll use your variant instead NToH\HToNL for my purpose!!!
Thanks again Mike..
Francesco
"Mike D Sutton" <EDais@mvps.org> ha scritto nel messaggio news:ezSLi7MzEHA.3976@TK2MSFTNGP09.phx.gbl...
> > I've an application that have to communicate with another (not mine) via
> > UDP.
> > The communication should be occur by structured messages with Long, Integer,
> > Single and Double fields!
> > I need to convert all fields in Big-Endian notation before sending.
> > For Long and Integer I found the two pairs of functions:
> >
> > NToHL, HToNL (for Long values)
> > NToHS, HToNS (for Integer values)
> >
> > but there isn't anything about Single and Double.
> > Can you help me to find something like:
> >
> > NToHFloat32, HToNFloat32 (for Single values)
> > NToHFloat64, HToNFloat64 (for Double values)
> > ????
> >
> > If there aren't APIs that perform these functions, can you help me in
> > another way?
>
> Here's a generic routine in VB code for flipping any number of bytes and wrapper functions for specifically flipping singles and
> doubles:
>
> '***
> Private Declare Sub GetByte Lib "MSVBVM60.dll" Alias "GetMem1" (ByRef inSrc As Long, ByRef inDst As Byte)
> Private Declare Sub PutByte Lib "MSVBVM60.dll" Alias "PutMem1" (ByRef inDst As Long, ByVal inSrc As Byte)
>
> Private Sub FlipBytes(ByVal inSrc As Long, ByVal inDst As Long, ByVal inCount As Long)
> Dim LoopBytes As Long
> Dim ThisByte As Byte
>
> For LoopBytes = 0 To (inCount - 1)
> Call GetByte(ByVal (inSrc + inCount - LoopBytes - 1), ThisByte)
> Call PutByte(ByVal (inDst + LoopBytes), ThisByte)
> Next LoopBytes
> End Sub
>
> Private Function FlipFloat(ByVal inFloat As Single) As Single
> Call FlipBytes(ByVal VarPtr(inFloat), ByVal VarPtr(FlipFloat), LenB(inFloat))
> End Function
>
> Private Function FlipDouble(ByVal inDouble As Double) As Double
> Call FlipBytes(ByVal VarPtr(inDouble), ByVal VarPtr(FlipDouble), LenB(inDouble))
> End Function
> '***
>
> Hope this helps,
>
> Mike
>
>
> - Microsoft Visual Basic MVP -
> E-Mail: EDais@mvps.org
> WWW: http://EDais.mvps.org/
>
>
- Next message: Dave: "Re: String patterns. How to ?"
- Previous message: J French: "Re: VB component works correctly only in debug mode"
- In reply to: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Next in thread: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Reply: Mike D Sutton: "Re: Little\Big-Endian Single and Double values"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|