VBspeed / Bits / ShiftRightZ
VBspeed © 2000-10, updated: 09-Oct-2001
ShiftRightZ


The Definition
Function ShiftRightZ
Shifts the bits to the right the specified number of positions and returns the new value.
Bits "falling off" the right edge do not wrap around. Fill bits coming in from left are 0 (zero, hence "ShiftRightZ", see ShiftRight for the alternative signbit-fill-in version).

Java has an operator for this job: ">>>".
Declaration
Function ShiftRightZ(Value As Long, ShiftCount as Long) As Long
Arguments
Valuevalue to use for operation
ShiftCountnumber of positions to shift, valid range is 0 thru 31.
You may use this function (VB5/6-compatible) to verify the correctness of your code.


The Charts
Calls
 lRet = ShiftRightZ(Value, ShiftCount)
Call 1 Value = 256
ShiftCount = 8
Call 2 Value = &H87654321
ShiftCount = 24
 VB5
CodeAuthorDopingNotes
ShiftRightZ01 ThomasAPI 
ShiftRightZ02 Donald  
ShiftRightZ03 Donald  
ShiftRightZ04 VB2TheMax  
ShiftRightZ05 PaulAPI,ASM 
ShiftRightZ06 Jost  
ShiftRightZ07 Jost  
ShiftRightZ08 Jost  
Call 1
88.070.302µs
43.840.144µs
64.740.177µs
77.650.286µs
11.000.037µs
54.010.150µs
31.550.058µs
21.460.055µs
Call 2
88.080.303µs
67.540.282µs
54.850.182µs
77.640.286µs
11.000.037µs
44.230.159µs
31.480.055µs
21.390.052µs
 VB6
CodeAuthorDopingNotes
ShiftRightZ01 ThomasAPI 
ShiftRightZ02 Donald  
ShiftRightZ03 Donald  
ShiftRightZ04 VB2TheMax  
ShiftRightZ05 PaulAPI,ASM 
ShiftRightZ06 Jost  
ShiftRightZ07 Jost  
ShiftRightZ08 Jost  
Call 1
88.760.328µs
43.840.144µs
64.800.180µs
77.550.283µs
11.000.037µs
54.020.151µs
31.610.060µs
21.540.058µs
Call 2
88.760.329µs
77.660.288µs
54.790.180µs
67.520.283µs
11.000.038µs
44.220.159µs
31.530.058µs
21.460.055µs
Conclusions
05, 07, 08 are all very fast. Your choice.
Mail your code! How to read all those numbers


The Code
ShiftRightZ01
added 18-Dec-2000
Doping: API
Private Type LARGEINT
  Long1 As Long
  Long2 As Long
End Type

Private Declare Function RLIShiftRight Lib "ntdll" Alias "RtlLargeIntegerShiftRight" _
    (ByVal Val1 As Long, ByVal Val2 As Long, ByVal ShiftCount As Long) As LARGEINT

Public Function ShiftRightZ01(Value As Long, ByVal ShiftCount As Long) As Long ' by Thomas Kabir (contact@vbfrood.de, http://www.vbfrood.de), 20001215 Dim Result As LARGEINT Result = RLIShiftRight(Value, 0, ShiftCount) ShiftRightZ01 = Result.Long1 End Function
Author's comments:
Donald's comments:

top | charts


ShiftRightZ02
submitted 18-Dec-2000 by Donald Lessau  
Doping: none
Public Function ShiftRightZ02(Value As Long, ByVal ShiftCount As Long) As Long
' by Donald, donald@xbeat.net, 20001215
  
  Select Case ShiftCount
  Case 1 To 31
    If Value And &H80000000 Then
      ShiftRightZ02 = Value And Not &H80000000
      ShiftRightZ02 = ShiftRightZ02 \ 2
      ShiftRightZ02 = ShiftRightZ02 Or &H40000000
      For ShiftCount = 1 To ShiftCount - 1
        ShiftRightZ02 = ShiftRightZ02 \ 2
      Next
    Else
      ShiftRightZ02 = Value
      For ShiftCount = 1 To ShiftCount
        ShiftRightZ02 = ShiftRightZ02 \ 2
      Next
    End If
  Case 0
    ' ret unchanged
    ShiftRightZ02 = Value
  End Select
  
End Function
Author's comments:
Donald's comments:

top | charts


ShiftRightZ03
submitted 18-Dec-2000 by Donald Lessau  
Doping: none
Public Function ShiftRightZ03(Value As Long, ByVal ShiftCount As Long) As Long
' by Donald, donald@xbeat.net, 20001215
  
  Select Case ShiftCount
  Case 1 To 31
    If Value And &H80000000 Then
      ShiftRightZ03 = (Value And Not &H80000000) \ 2
      ShiftRightZ03 = ShiftRightZ03 Or &H40000000
      ShiftRightZ03 = ShiftRightZ03 \ Pow2(ShiftCount - 1)
    Else
      ShiftRightZ03 = Value \ Pow2(ShiftCount)
    End If
  Case 0
    ' ret unchanged
    ShiftRightZ03 = Value
  End Select

End Function
Author's comments: See Pow2
Donald's comments:

top | charts


ShiftRightZ04
added 18-Dec-2000
Doping: none
Public Function ShiftRightZ04(ByVal Value As Long, ByVal times As Long) As Long
' by The VB2TheMax Team (as "ShiftRight"), 20001217
    ' we need to create a mask of 1's corresponding to the
    ' digits in VALUE that will be retained in the result
    Dim mask As Long, signBit As Long
    
    ' return zero if too many times
    If times >= 32 Then Exit Function
    ' added by Donald (else crash):
    If times < 0 Then Exit Function
    ' return the value if zero times
    If times = 0 Then ShiftRightZ04 = Value: Exit Function
    
    ' evaluate the sign bit in advance
    signBit = (Value < 0) And Pow2(31 - times)
    ' create a mask with 1's for the digits that will be preserved
    If times < 31 Then
        ' if times=31 then the mask is zero
        mask = Not (Pow2(times) - 1)
    End If
    ' clear all the digits that will be discarded, and
    ' also clear the sign bit
    Value = (Value And &H7FFFFFFF) And mask
    ' do the shift, without any problem, and add the sign bit
    ShiftRightZ04 = (Value \ Pow2(times)) Or signBit
End Function
Author's comments: See Pow2
Donald's comments:

top | charts


ShiftRightZ05
submitted 26-Sep-2001 by Paul    http://www.syix.com/wpsjr1/index.html
revision 001, 09-Oct-2001
Doping: API and ASM (Assembly Snippets), all three Shift operations wrapped in module (download the module, VB5-compatible, zipped, 2KB)
The complete code is a bit too long to be displayed here ... download it to have a look.

Here's the ASM bytes (for each of the three Shift operations):
Private Const SHLCode As String = "8A4C240833C0F6C1E075068B442404D3E0C20800"  ' shl eax, cl = D3 E0
Private Const SHRCode As String = "8A4C240833C0F6C1E075068B442404D3E8C20800"  ' shr eax, cl = D3 E8
Private Const SARCode As String = "8A4C240833C0F6C1E075068B442404D3F8C20800"  ' sar eax, cl = D3 F8
Author's comments:
' These functions are inline asm hacks for SHL and SHR aka << >>
' in C, C++.  They shift using the following ASM code:

' mov eax, [esp+4]
' mov cl, [esp+8]
' shr eax, cl   ; or shl eax, cl
' ret 8

' Only the first five bits of the cl register are evaluated for either op code.
' So, as in C, if you do shl 8, 33 its the equivalent of shl 8, 1
' as (33 AND 31) = 1

' or shr 8, -1 is the same as shr 8, 31 as (255 and 31) = 31

' Personally, I think VB is sorely in need of true bit shifting ops,
' but MS assumes we VB programmers are a mindless bunch :(

' NOTE: YOU *MUST* CALL InitFunctionsShift() BEFORE USING THESE FUNCTIONS
Donald's comments:

top | charts


ShiftRightZ06
submitted 28-Sep-2001 by Jost Schwider    vb-tec.de
Doping: none
Public Static Function ShiftRightZ06(Value As Long, ByVal ShiftCount As Long) As Long
' by Jost Schwider, jost@schwider.de, 20010928
  Dim Pow2(0 To 31) As Long
  Dim i As Long
  
  Select Case ShiftCount
  Case 1 To 31
  
    'Ggf. Initialisieren:
    If i = 0 Then
      Pow2(0) = 1
      For i = 1 To 30
        Pow2(i) = 2 * Pow2(i - 1)
      Next i
    End If
    
    'Los gehts:
    If Value And &H80000000 Then
      'Vorzeichen, also Achtung:
      ShiftRightZ06 = (((Value And Not &H80000000) \ 2) Or &H40000000) \ Pow2(ShiftCount - 1)
    Else
      'Einfacher Fall, da kein Vorzeichen:
      ShiftRightZ06 = Value \ Pow2(ShiftCount)
    End If
  
  Case 0
  
    ShiftRightZ06 = Value
  
  End Select
End Function
Author's comments:
Donald's comments:

top | charts


ShiftRightZ07
submitted 01-Oct-2001 by Jost Schwider    vb-tec.de
Doping: none
Public Function ShiftRightZ07(ByVal Value As Long, ByVal ShiftCount As Long) As Long
' by Jost Schwider, jost@schwider.de, 20010928
  If ShiftCount = 0 Then
    ShiftRightZ07 = Value
  Else
    If Value And &H80000000 Then
      Value = (Value And &H7FFFFFFF) \ 2 Or &H40000000
      ShiftCount = ShiftCount - 1
    End If
    
    Select Case ShiftCount
    Case 0&:  ShiftRightZ07 = Value
    Case 1&:  ShiftRightZ07 = Value \ &H2&
    Case 2&:  ShiftRightZ07 = Value \ &H4&
    Case 3&:  ShiftRightZ07 = Value \ &H8&
    Case 4&:  ShiftRightZ07 = Value \ &H10&
    Case 5&:  ShiftRightZ07 = Value \ &H20&
    Case 6&:  ShiftRightZ07 = Value \ &H40&
    Case 7&:  ShiftRightZ07 = Value \ &H80&
    Case 8&:  ShiftRightZ07 = Value \ &H100&
    Case 9&:  ShiftRightZ07 = Value \ &H200&
    Case 10&: ShiftRightZ07 = Value \ &H400&
    Case 11&: ShiftRightZ07 = Value \ &H800&
    Case 12&: ShiftRightZ07 = Value \ &H1000&
    Case 13&: ShiftRightZ07 = Value \ &H2000&
    Case 14&: ShiftRightZ07 = Value \ &H4000&
    Case 15&: ShiftRightZ07 = Value \ &H8000&
    Case 16&: ShiftRightZ07 = Value \ &H10000
    Case 17&: ShiftRightZ07 = Value \ &H20000
    Case 18&: ShiftRightZ07 = Value \ &H40000
    Case 19&: ShiftRightZ07 = Value \ &H80000
    Case 20&: ShiftRightZ07 = Value \ &H100000
    Case 21&: ShiftRightZ07 = Value \ &H200000
    Case 22&: ShiftRightZ07 = Value \ &H400000
    Case 23&: ShiftRightZ07 = Value \ &H800000
    Case 24&: ShiftRightZ07 = Value \ &H1000000
    Case 25&: ShiftRightZ07 = Value \ &H2000000
    Case 26&: ShiftRightZ07 = Value \ &H4000000
    Case 27&: ShiftRightZ07 = Value \ &H8000000
    Case 28&: ShiftRightZ07 = Value \ &H10000000
    Case 29&: ShiftRightZ07 = Value \ &H20000000
    Case 30&: ShiftRightZ07 = Value \ &H40000000
    Case 31&: ShiftRightZ07 = &H0&
    End Select
  End If
End Function
Author's comments:
Donald's comments:

top | charts


ShiftRightZ08
submitted 01-Oct-2001 by Jost Schwider    vb-tec.de
Doping: none
Public Function ShiftRightZ08(ByVal Value As Long, ByVal ShiftCount As Long) As Long
' by Jost Schwider, jost@schwider.de, 20011001
  If Value And &H80000000 Then
    Select Case ShiftCount
    Case 0&:  ShiftRightZ08 = Value
    Case 1&:  ShiftRightZ08 = &H40000000 Or (Value And &H7FFFFFFF) \ &H2&
    Case 2&:  ShiftRightZ08 = &H20000000 Or (Value And &H7FFFFFFF) \ &H4&
    Case 3&:  ShiftRightZ08 = &H10000000 Or (Value And &H7FFFFFFF) \ &H8&
    Case 4&:  ShiftRightZ08 = &H8000000 Or (Value And &H7FFFFFFF) \ &H10&
    Case 5&:  ShiftRightZ08 = &H4000000 Or (Value And &H7FFFFFFF) \ &H20&
    Case 6&:  ShiftRightZ08 = &H2000000 Or (Value And &H7FFFFFFF) \ &H40&
    Case 7&:  ShiftRightZ08 = &H1000000 Or (Value And &H7FFFFFFF) \ &H80&
    Case 8&:  ShiftRightZ08 = &H800000 Or (Value And &H7FFFFFFF) \ &H100&
    Case 9&:  ShiftRightZ08 = &H400000 Or (Value And &H7FFFFFFF) \ &H200&
    Case 10&: ShiftRightZ08 = &H200000 Or (Value And &H7FFFFFFF) \ &H400&
    Case 11&: ShiftRightZ08 = &H100000 Or (Value And &H7FFFFFFF) \ &H800&
    Case 12&: ShiftRightZ08 = &H80000 Or (Value And &H7FFFFFFF) \ &H1000&
    Case 13&: ShiftRightZ08 = &H40000 Or (Value And &H7FFFFFFF) \ &H2000&
    Case 14&: ShiftRightZ08 = &H20000 Or (Value And &H7FFFFFFF) \ &H4000&
    Case 15&: ShiftRightZ08 = &H10000 Or (Value And &H7FFFFFFF) \ &H8000&
    Case 16&: ShiftRightZ08 = &H8000& Or (Value And &H7FFFFFFF) \ &H10000
    Case 17&: ShiftRightZ08 = &H4000& Or (Value And &H7FFFFFFF) \ &H20000
    Case 18&: ShiftRightZ08 = &H2000& Or (Value And &H7FFFFFFF) \ &H40000
    Case 19&: ShiftRightZ08 = &H1000& Or (Value And &H7FFFFFFF) \ &H80000
    Case 20&: ShiftRightZ08 = &H800& Or (Value And &H7FFFFFFF) \ &H100000
    Case 21&: ShiftRightZ08 = &H400& Or (Value And &H7FFFFFFF) \ &H200000
    Case 22&: ShiftRightZ08 = &H200& Or (Value And &H7FFFFFFF) \ &H400000
    Case 23&: ShiftRightZ08 = &H100& Or (Value And &H7FFFFFFF) \ &H800000
    Case 24&: ShiftRightZ08 = &H80& Or (Value And &H7FFFFFFF) \ &H1000000
    Case 25&: ShiftRightZ08 = &H40& Or (Value And &H7FFFFFFF) \ &H2000000
    Case 26&: ShiftRightZ08 = &H20& Or (Value And &H7FFFFFFF) \ &H4000000
    Case 27&: ShiftRightZ08 = &H10& Or (Value And &H7FFFFFFF) \ &H8000000
    Case 28&: ShiftRightZ08 = &H8& Or (Value And &H7FFFFFFF) \ &H10000000
    Case 29&: ShiftRightZ08 = &H4& Or (Value And &H7FFFFFFF) \ &H20000000
    Case 30&: ShiftRightZ08 = &H2& Or (Value And &H7FFFFFFF) \ &H40000000
    Case 31&: ShiftRightZ08 = &H1&
    End Select
  Else
    Select Case ShiftCount
    Case 0&:  ShiftRightZ08 = Value
    Case 1&:  ShiftRightZ08 = Value \ &H2&
    Case 2&:  ShiftRightZ08 = Value \ &H4&
    Case 3&:  ShiftRightZ08 = Value \ &H8&
    Case 4&:  ShiftRightZ08 = Value \ &H10&
    Case 5&:  ShiftRightZ08 = Value \ &H20&
    Case 6&:  ShiftRightZ08 = Value \ &H40&
    Case 7&:  ShiftRightZ08 = Value \ &H80&
    Case 8&:  ShiftRightZ08 = Value \ &H100&
    Case 9&:  ShiftRightZ08 = Value \ &H200&
    Case 10&: ShiftRightZ08 = Value \ &H400&
    Case 11&: ShiftRightZ08 = Value \ &H800&
    Case 12&: ShiftRightZ08 = Value \ &H1000&
    Case 13&: ShiftRightZ08 = Value \ &H2000&
    Case 14&: ShiftRightZ08 = Value \ &H4000&
    Case 15&: ShiftRightZ08 = Value \ &H8000&
    Case 16&: ShiftRightZ08 = Value \ &H10000
    Case 17&: ShiftRightZ08 = Value \ &H20000
    Case 18&: ShiftRightZ08 = Value \ &H40000
    Case 19&: ShiftRightZ08 = Value \ &H80000
    Case 20&: ShiftRightZ08 = Value \ &H100000
    Case 21&: ShiftRightZ08 = Value \ &H200000
    Case 22&: ShiftRightZ08 = Value \ &H400000
    Case 23&: ShiftRightZ08 = Value \ &H800000
    Case 24&: ShiftRightZ08 = Value \ &H1000000
    Case 25&: ShiftRightZ08 = Value \ &H2000000
    Case 26&: ShiftRightZ08 = Value \ &H4000000
    Case 27&: ShiftRightZ08 = Value \ &H8000000
    Case 28&: ShiftRightZ08 = Value \ &H10000000
    Case 29&: ShiftRightZ08 = Value \ &H20000000
    Case 30&: ShiftRightZ08 = Value \ &H40000000
    Case 31&: ShiftRightZ08 = &H0&
    End Select
  End If
End Function
Author's comments:
Donald's comments:

top | charts




VBspeed © 2000-10 by Donald Lessau