BiteWise.ShiftRight

I’m porting a code and I thought Bitwise.ShiftRight was what I’m trying to port but it only gives me the same answer if the number is positive, so now I don’t know if
A) it’s my lack of porting abilities
B) it isn’t a Bitwise.ShiftRight
C) Bitwise.ShiftRight doesn’t handle negative numbers (or many other options)

This is how I translated a VB6 ShiftRight and if lValue is a positive number it’s the same as Bitwise.ShiftRight but not if it’s a negative number

[code] Dim ReturnValue As Integer
If iShiftBits = 0 Then
Return lValue
ElseIf iShiftBits = 31 Then
If (lValue And &H80000000) <> 0 Then
ReturnValue = 1
Else
ReturnValue = 0
End If
Return ReturnValue
ElseIf iShiftBits < 0 Or iShiftBits > 31 Then
//Error but it seems to be 24 or 0 everytime
End If
ReturnValue = (lValue And &H7FFFFFFE) \ m_l2Power(iShiftBits)//array of 2^

If (lValue And &H80000000) <> 0 Then
ReturnValue = (ReturnValue Or (&H40000000 \ m_l2Power(iShiftBits - 1)))
End If
Return ReturnValue[/code]

Bitwise operators don’t care (or know) about the “sign”… they operate on the bits only, and a negative number is stored as a “1’s complement” (or is it 2’s complement, I never remember) format

+1 as a 16bit integer is 0000 0000 0000 0001
-1 as a 16 bit integer is 1111 1111 1111 1111

but those same bit values (well the negative one anyways) is a totally different value if it is a UInt instead of an Integer

If Xojo had arithmetic shift left and arithmetic shift right operations (as opposed to logical shift operations), then the sign would be properly taken care of. Lacking that, you would be further ahead simply to divide by the appropriate power of 2 for a right shift and multiply by power of 2 for left shift:

n=numberToBeShifted/2^nPositions 'for arithmetic right shift
n=numberToBeShifted*2^nPositions 'for arithmetic left shift

Thanks but I still don’t understand what I’ve done wrong porting the VB6 code
Bitwise.ShiftRight(-2047271774, 8) = -7997156
-2047271774/(2^8) = -7997156
my code = 8780060

I Googled the VB6 shift function and saw some uncomplimentary comments about how the shift is handled. I can’t claim I read enough to understand it, but I believe the problem you are having is just because the bitwise shift functions operate differently in VB6 and XOJO. So if you need to convert code, I suggest just replacing the VB6 shift code with the multiplication equivalent: in your example -2047271774/(2^8) = -7997156.

Thanks, I know the vb6 code works as far as encrypting and decrypting, so I guess I’ll just have to replace all of it and see if it works with Xojo code.

[quote=298679:@Jym Morton]Thanks but I still don’t understand what I’ve done wrong porting the VB6 code
Bitwise.ShiftRight(-2047271774, 8) = -7997156
-2047271774/(2^8) = -7997156
my code = 8780060[/quote]
It’s quite clear from these results that VB6 does an arithmetic shift whereas Xojo does a logical shift.

Edit:
One point that I overlooked is that there may be a difference between an arithmetic right shift and division by power of 2 when dealing with negative numbers. This is explained in the linked article. I suggest you test the VB6 code to see what happens when you do a right shift of -1.

Using the VB6 code it is 16777215 with Bitwise it is -1 and with 2^8 it is 0 yikes so now there are 3 answers :frowning:

Then I suggest the VB code is wrong…

16777215 is 0x00FF FFFF which is a 32bit integer
in a 32bit Integer, -1 would be 0xFFFF FFFF

16777215 shifted right is 8388607 or 0x007F FFFF

@Robert Weaver
Looking at the Binary in the debugger however it looks like VB code does the logic shift and Xojo does the Arithmetic Shift.
-1 for bitwise.Shift Right ends up a hole pile of 1s and according to that Wiki page that’s what would happen with a Right Arithmetic Shift and having 8 zeros out the front (16777215) would be the logical Shift Right as the MSB is replaced with a zero for each move to the right.

How do you do a confused emoji?

Sorry, I got things a bit mixed up earlier when I looked at your results. If you right shift a negative number and the result is negative then that indicates that it was an arithmetic shift. A logical right shift will always produce a positive number, because a zero will enter the most significant bit position, and that is the sign bit. If you need to exactly duplicate the VB6 operation, then you’ll probably have to add a bit more code. You could do a bitwise right shift followed by a bitwise AND to zero the upper bits.

@Robert Weaver
I’m very bitdumb, but the pictures help :slight_smile: So if my shift is 8 my AND would be 00000000 and 24 1’s? or 16777215 as seen above?

Easier to work in hex. You would AND with the hex value &h00FFFFFF.

to remove the sign bit from a 32bit Integer? no… you would AND it with &H7FFFFFFF

The problem is that an 8 bit right shift will propagate that bit along 8 bit positions. So they all need to be deleted.

or you AND it BEFORE you shift it

I have all 31 in an array so it’s pretty simple with any shift. It’s funny because I need to draw it on graph paper to figure out any shift, AND, OR. Not looking forward to my next Method, it’s got Xor that sounds like fun :slight_smile:

perhaps its just me, but I have found Boolean Algebra to be quite easy… of course I had to learn it way before the IBM PC ever saw the light of day…

AND OR NOT XOR SHL SHR ROL ROR, Truth Tables, 1’s complement, 2’s complement ( I will admit I confuse those to this very day)

was almost impossible to write Assembler code without a good handle on these functions

@Robert Weaver I’ve put in about 100 positive numbers and they seem to be unaffected by the AND. Is this always true so I don’t have have to run an if statement to test the number being shifted?
if LValue > 0 then

(LValue, 8)
Else

(LValue, 8) AND 16777215
End If

One very very important thing… make sure you are using the CORRECT Integer Datatype

Dim x as INTEGER // is either 32bit or 64bit depending on how you compile..
Dim x1 as Int32  // is ALWAYS 32bit regardless of how you compile

So if you are doing a 64bit compile, and using INTEGER, then that AND will NOT affect the values, because you are no where near the limit

and 1677215 is only 24 bits anyways…

in VB6 … Integer was ONLY 32 bit

So you need to make sure you are using the proper datatype, understand the effects of SHR (shift right) and AND

any NEGATIVE value will be different series of BITS in a 32bit vs 64bit (or 16bit or 8bit) INTEGER

dim x as Int8 = -1  is &HFF
but  in a Int16 &hFF is 255 whereas -1 is &hFFFF
which is 65535 in Int32 etc. etc.

So start by NOT using INTEGER as your datatype, use Int32… or if you really don’t care about negative numbers use UInt32