PDA

View Full Version : shifting negative long vars



Kamikaze47
- 26th April 2010, 14:06
I'm trying to divide a long variable by 256, so I tried to shift 8 bits right (>>8), but it looks like its also shifting the MSB as well which is messing up the sign.

Should PBPL be able to handle shifting signed longs without messing up the sign?

For example:

if longvar has the value of -256, shifting it 8 times right should result in -1, instead I get 16,777,215

ScaleRobotics
- 26th April 2010, 15:26
I can only answer half your question. The sign bit in a long is bit 31. So when you shift right 8 bits, it moves the sign bit as well, which shows up as bit 23 after your shift. To fix that, read the sign bit, clear the sign bit, then shift, then set the sign bit again.

However, the value you are getting is 111111111111111111111111 in binary. And that does not make sense ... to me anyway. I would have expected 100000000000000000000001

But, are you dividing by 256 because of a sensor value? If so, shouldn't you be dividing by 255? Otherwise 5 volt reading will never be reached with divisor of 256. Divisor by 255, and it is possible to get to 5 volts.

Kamikaze47
- 26th April 2010, 15:31
I know why i'm getting 111111111111111111111111

Its because longs use 2's compliment for negative numbers, so:

-1 = 11111111 11111111 11111111 11111111
-2 = 11111111 11111111 11111111 11111110
-3 = 11111111 11111111 11111111 11111101

and so on

I was just surprised that since PBP now supports signed longs, that they didnt build in support for doing something as simple as shifting without messing up the signing

Kamikaze47
- 26th April 2010, 17:39
ive solved the problem with this code to divide x by 256:


IF x.31 then ' if negative:
x=~x+1 ' convert from 2s complement
x=x>>8 ' shift
x=~(x-1) ' convert back to 2s complement
x.31=1 ' set signed bit (negative)
if x=$80000000 then x=0 ' negative 0 is 0
ELSE ' else (positive):
x=x>>8 ' shift
ENDIF

Kamikaze47
- 26th April 2010, 17:51
after some playing i found a simpler way:


negative=x.31 ' Save the sign bit
x=(ABS x)>>8 ' Shift the absolute value
IF negative THEN x=0-x ' Make negative again