November 28, 2020, 02:19:50 PM

Author Topic: [bmx] Reverse bytes and bits by N [ 1+ years ago ]  (Read 397 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Reverse bytes and bits by N [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Reverse bytes and bits
Author : N
Posted : 1+ years ago

Description : Pretty simple, it just reverse the byte and bit order.

For an example:
Code: [Select]
Local p@ Ptr = "blah".ToWString( )

ReverseBytes( p, 8, False )
Print Bin( Int Ptr(p)[0] )

Print String.FromShorts( Short Ptr(p), 8 )

ReverseBytes( p, 8, False )
Print Bin( Int Ptr(p)[0] )

ReverseBytes( p, 8, True )
Print Bin( Int Ptr(p)[0] )

Print String.FromShorts( Short Ptr(p), 8 )

ReverseBytes( p, 8, True )
Print Bin( Int Ptr(p)[0] )

Print String.FromShorts( Short Ptr(p), 8 )

ReverseBytes( p, 8, True )
Print Bin( Int Ptr(p)[0] )

ReverseBytes( p, 8, False )
Print Bin( Int Ptr(p)[0] )

Print String.FromShorts( Short Ptr(p), 8 )

ReverseBytes( p, 8, False )
Print Bin( Int Ptr(p)[0] )

ReverseBytes( p, 8, True )
Print Bin( Int Ptr(p)[0] )

Print String.FromShorts( Short Ptr(p), 8 )

Local t% = Millisecs( )
For Local i% = 0 To 99999
    ReverseBytes(p,8,True)
Next
t = Millisecs( ) - t
Print "Time taken with rbits as True: "+t+"ms"
Print "Time taken per call with rbits as True average: "+(t*0.00001)+"ms"

t = Millisecs( )
For Local i% = 0 To 199999
    ReverseBytes(p,8,False)
Next
t = Millisecs( ) - t
Print "Time taken with rbits as False: "+t+"ms"
Print "Time taken per call with rbits as False average: "+(t*0.00001)+"ms"

MemFree( p ) ' Ok, we're done with the memory

Print Bin(%10000000)[24..]
Print Bin(ReverseBits( %10000000 ))[24..]

Print Bin(%11000000)[24..]
Print Bin(ReverseBits( %11000000 ))[24..]

Print Bin(%10100000)[24..]
Print Bin(ReverseBits( %10100000 ))[24..]

Print Bin(%00000011)[24..]
Print Bin(ReverseBits( %00000011 ))[24..]

Input( )


It's fun to use. [/i]

Code :
Code: BlitzMax
  1. Function ReverseBytes( p@ Ptr, sz%, rbits%=0 )
  2.     Local szh% = Int(Floor(sz*.5))
  3.     sz :- 1
  4.     If rbits>0 Then
  5.         For Local i:Int = 0 To szh-1
  6.             szh = p[i] ' Because szh is only used once, we can reuse it here
  7.             p[i] = ReverseBits(p[sz-i])
  8.             p[sz-i] = ReverseBits(szh)
  9.         Next
  10.         sz :+ 1
  11.         If Int(sz*.5) <> Ceil((sz*.5)-.1) Then
  12.             sz = Int(Ceil(sz*.5))
  13.             p[sz] = ReverseBits(p[sz])
  14.         EndIf
  15.     Else
  16.         For Local i:Int = 0 To szh-1
  17.             szh = p[i]
  18.             p[i] = p[sz-i]
  19.             p[sz-i] = szh
  20.         Next
  21.     EndIf
  22. End Function
  23.  
  24. Function ReverseBitsA@( p@ )
  25.     ?Debug
  26.     Return (p & %1) Shl 7..
  27.     | ((p&%10000000) Shr 7)..
  28.     | (p & %10) Shl 5..
  29.     | ((p&%1000000) Shr 5)..
  30.     | (p & %100) Shl 3..
  31.     | ((p&%100000) Shr 3)..
  32.     | (p & %1000) Shl 1..
  33.     | ((p&%10000) Shr 1)
  34.     ?
  35.     Local p2:Int = ((p & %11110000) Shr 4) | ((p & %1111) Shl 4)
  36.     p =((p & %11001100) Shr 2) | ((p & %110011) Shl 2)
  37.     Return ((p & %10101010) Shr 1) | ((p & %1010101) Shl 1)
  38. End Function


Comments :


ImaginaryHuman(Posted 1+ years ago)

 
Code: [Select]
Function ReverseBits@( p@ )
   Local p2:Int=((p & %11110000) Shr 4) | ((p & %1111) Shl 4)
   p=((p2 & %11001100) Shr 2) | ((p2 & %110011) Shl 2)
   Return ((p & %10101010) Shr 1) | ((p & %1010101) Shl 1)
End Function
'6 shifts 6 and's 3 or's instead of 8 , 8 and 7 - should be up to 25% faster.The only downside is having to store the interim values into a variable so you can then read in the changes to continue the operation.You can probably optimize your byte sort routine in much the same way and it should be a lot faster. It's a binary flip, so if you're flipping an Int it should only take 5 passes of swapping the sets of bits. Much better than doing it a bit at a time.I have no idea what your example program is trying to do. :-)


N(Posted 1+ years ago)

 For some reason that's only faster in release mode, so I'll use this:
Code: [Select]
Function ReverseBitsA@( p@ )
    ?Debug
    Return (p & %1) Shl 7..
    | ((p&%10000000) Shr 7)..
    | (p & %10) Shl 5..
    | ((p&%1000000) Shr 5)..
    | (p & %100) Shl 3..
    | ((p&%100000) Shr 3)..
    | (p & %1000) Shl 1..
    | ((p&%10000) Shr 1)
    ?
    Local p2:Int = ((p & %11110000) Shr 4) | ((p & %1111) Shl 4)
    p =((p & %11001100) Shr 2) | ((p & %110011) Shl 2)
    Return ((p & %10101010) Shr 1) | ((p & %1010101) Shl 1)
End Function
Bit bloated, but it's fast in both situations.Example program is just trying to show that it's fun to use.  It's pretty useless for a lot of things, but it's fun to use it for completely bizarre things too. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal