Easier way to convert big-endian to little-endian?

New to FreeBASIC? Post your questions here.
marcov
Posts: 3020
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:

Re: Easier way to convert big-endian to little-endian?

Postby marcov » Jan 18, 2017 4:53

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
St_W
Posts: 1508
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Easier way to convert big-endian to little-endian?

Postby St_W » Jan 18, 2017 11:15

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

Endianess is typically on a per-Byte level, so one doesn't need to revert all the bits.

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: viewtopic.php?p=228153
D.J.Peters
Posts: 8189
Joined: May 28, 2005 3:28
Contact:

Re: Easier way to convert big-endian to little-endian?

Postby D.J.Peters » Jan 18, 2017 15:27

Not the fastes solution in BASIC but easy to read.

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
MrSwiss
Posts: 3635
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Easier way to convert big-endian to little-endian?

Postby MrSwiss » Jan 18, 2017 18:32

Yet another approach, using Unions, which results in simple assignments in the Functions.
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
paul doe
Posts: 1324
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Easier way to convert big-endian to little-endian?

Postby paul doe » Apr 10, 2018 4:40

I'm always amazed at how simple problems result in convoluted solutions:

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()

I'm sure anyone can follow the same pattern to implement 128 or 256-bit reversals ;)

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 8 guests