lrotl (long rotate left) function

Share your advanced PureBasic knowledge/code with the community.
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

lrotl (long rotate left) function

Post by ozzie »

I recently had a need to use lrotl (long rotate left) on unsigned longs, so I wrote this procedure:

Code: Select all

Procedure.l lrotl(pSource.l, pShift)
  ; long rotate left
  ; pShift is number of bits to rotate left
  Protected nTmp.l, nSource.l, nTarget.l
  Protected nBit0.l
  
  nSource = pSource
  If nSource < 0
    nBit0 = 1 << (pShift-1)
    nSource & $7FFFFFFF
  EndIf
  nTmp = nSource >> (32 - pShift)
  nTmp | nBit0
  nTarget = nSource << pShift
  nTarget | nTmp
  ProcedureReturn nTarget
EndProcedure
It's necessary to specifically handle negatives or the sign bit gets propagated down the long by >>.

Hope it's of use to someone.
ozzie
Enthusiast
Enthusiast
Posts: 443
Joined: Sun Apr 06, 2008 12:54 pm
Location: Brisbane, Qld, Australia
Contact:

Re: lrotl (long rotate left) function

Post by ozzie »

I've received a PM from "idle" that provides a more compact way of implementing rotate. Here it is, with macros for rotating 32-bit or 64-bit variables, and including examples slightly modified by myself:

Code: Select all

Macro RotLeft32(var,pp)   ;variables need to be uniquely named for all scopes  
  !if  defined  v_#var
    !ROL dword [v_#var],pp
  !else 
    !ROL dword [p.v_#var],pp
  !end If 
EndMacro 

Macro RotLeft64(var,pp) 
  !if defined v_#var
    !ROL qword [v_#var],pp
  !else 
    !ROL qword [p.v_#var],pp
  !end If    
EndMacro 

Procedure foo() 
  Protected pa.l 
  ; pa = 22345 
  pa = $ABCD1234
  Debug "$" + Hex(pa,#PB_Long) + ", %" + RSet(Bin(pa,#PB_Long),32,"0")
  RotLeft32(pa,24)
  Debug "$" + Hex(pa,#PB_Long) + ", %" + RSet(Bin(pa,#PB_Long),32,"0")
  
EndProcedure   

Global a.l 

; a = 12345 
a = $12345678
Debug "$" + Hex(a,#PB_Long) + ", %" + RSet(Bin(a,#PB_Long),32,"0")
RotLeft32(a,24)
Debug "$" + Hex(a,#PB_Long) + ", %" + RSet(Bin(a,#PB_Long),32,"0")

foo() 
Post Reply