See http://stackoverflow.com/questions/4245 ... 2-bit-word
For 32-bit the last routine is best. For 8 bit iirc lookup table, for a nibble if you want to save mem
Easier way to convert big-endian to little-endian?
Re: Easier way to convert big-endian to little-endian?
Endianess is typically on a per-Byte level, so one doesn't need to revert all the bits.marcov wrote:See http://stackoverflow.com/questions/4245 ... 2-bit-word
For 32-bit the last routine is best. For 8 bit iirc lookup table, for a nibble if you want to save mem
As mentioned earlier in this thread there's the BSWAP assembly instruction on x86/x64 systems for converting between Big-Endian and Little-Endian.
Your example probably belongs to that thread: http://freebasic.net/forum/viewtopic.php?p=228153
-
- Posts: 8586
- Joined: May 28, 2005 3:28
- Contact:
Re: Easier way to convert big-endian to little-endian?
Not the fastes solution in BASIC but easy to read.
Joshy
Joshy
Code: Select all
#macro SWAP16(v)
swap cptr(ubyte ptr,@v)[0],cptr(ubyte ptr,@v)[1]
#endmacro
#macro SWAP32(v)
swap cptr(ubyte ptr,@v)[0],cptr(ubyte ptr,@v)[3]
swap cptr(ubyte ptr,@v)[1],cptr(ubyte ptr,@v)[2]
#endmacro
dim as ushort v16 = &H0FF0
dim as ulong v32 = &HF00FF00F
print hex(v16,4)
SWAP16(v16)
print hex(v16,4)
?
print hex(v32,8)
SWAP32(v32)
print hex(v32,8)
sleep
Re: Easier way to convert big-endian to little-endian?
Yet another approach, using Unions, which results in simple assignments in the Functions.
Catering for 64bit INT's:
Catering for 64bit INT's:
Code: Select all
' x64_Big_Endian_Lil.bas -- 2017-01-18, MrSwiss
Union Lil_End
As ULongInt ULInt
Type
As UByte _0
As UByte _1
As UByte _2
As UByte _3
As UByte _4
As UByte _5
As UByte _6
As UByte _7
End Type
End Union
Union Big_End
As ULongInt ULInt
Type
As UByte _7
As UByte _6
As UByte _5
As UByte _4
As UByte _3
As UByte _2
As UByte _1
As UByte _0
End Type
End Union
Function LilToBig(ByVal x As ULongInt) As ULongInt
Dim As Lil_End L_end
Dim As Big_End ret
L_End.ULInt = x : ret.ULInt = 0
ret._0 = L_End._0 : ret._1 = L_End._1
ret._2 = L_End._2 : ret._3 = L_End._3
ret._4 = L_End._4 : ret._5 = L_End._5
ret._6 = L_End._6 : ret._7 = L_End._7
LilToBig = ret.ULInt
End Function
Function BigToLil(ByVal x As ULongInt) As ULongInt
Dim As Big_End B_end
Dim As Lil_End ret
B_End.ULInt = x : ret.ULInt = 0
ret._0 = B_End._0 : ret._1 = B_End._1
ret._2 = B_End._2 : ret._3 = B_End._3
ret._4 = B_End._4 : ret._5 = B_End._5
ret._6 = B_End._6 : ret._7 = B_End._7
BigToLil = ret.ULInt
End Function
' ======================
' testig code
Dim As ULongInt a = &hFF007F003F000100, b = LilToBig(a)
Print "original 'a': "; Hex(a, 16)
Print "inverted 'a': "; Hex(LilToBig(a), 16)
Print
Print "original 'b': "; Hex(b, 16)
Print "inverted 'b': "; Hex(BigToLil(b), 16)
Sleep
Re: Easier way to convert big-endian to little-endian?
I'm always amazed at how simple problems result in convoluted solutions:
I'm sure anyone can follow the same pattern to implement 128 or 256-bit reversals ;)
Code: Select all
#define loQWord( x ) ( clngInt( x and &h00000000ffffffff ) )
#define hiQWord( x ) ( clngInt( ( x shr 32 ) and &h00000000ffffffff ) )
#define swap16( x ) ( cshort( ( ( loByte( x ) shl 8 ) or ( hiByte( x ) ) ) ) )
#define swap32( x ) ( clng( clng( swap16( loWord( x ) ) shl 16 ) or clng( swap16( hiWord( x ) ) and &h0000ffff ) ) )
#define swap64( x ) ( clngInt( clngInt( swap32( loQWord( x ) ) shl 32 ) or clngInt( swap32( hiQWord( x ) ) and &h00000000ffffffff ) ) )
dim as short s = -32123
dim as long l = &habcdef12
dim as longInt i = &habcdef1234567890
? hex( s ), hex( swap16( s ) ), s
? hex( l ), hex( swap32( l ) ), l
? hex( i ), hex( swap64( i ) ), i
?
'' Integrity check
? hex( swap16( swap16( s ) ) ), s
? hex( swap32( swap32( l ) ) ), l
? hex( swap64( swap64( i ) ) ), i
sleep()