Something screwy with rotate?

rossw

Active Member
I've used rotate (ROTL and ROTR) before but can't remember ever needing to use all 32 bits before.
Well, today I've tried it and am getting completely screwy results!
 
Consider the following snippet.

START
set var1 2048
x:
delay 1000
rotr var1 1 var1
goto x
END


You'd expect it to count 2048, 1024, 512... which it does. But once it rotates the bit out 0 and into bit 31, it seems bit 31 remains ALWAYS set. After a further 31 rotates, we end up with -1 (and stay at -1 forever more)
 
Similarly, changing the   rotr    to    rotl   we would expect to see 2048, 4096, 8192, etc... which we do... until bit 31 gets set, then we get to -1 and again, stay there.
 
This isn't "rotate" as I know it - am I doing something wrong, or is this a bug in the code?
 
 
Ross,
 
VAR is a 32bit signed number. When rotate 31 bit, it becomes -1.  then keep rotating will have two expectations, one is to rotate that totally out becoming zero, another is to feed the that bit into the other end of the bit stream and keep repeating.  Maybe we should treat them as unsigned 32 bit number, so that it could be rotate out the sign bit.
 
Play with it. It simply is not doing a bitwise rotate.
If you load a bit pattern, then rotate it 32-bits left or right, it should be the same as when you started.... but it's not.
 
Ross,
 
I think we see what you talked about, but no sure how to make it work ideally yet.
The problem is that when shifting toward -4,-2, then to -1, internally, the bit patter for -1 is 0xFFFF, all 1 in all positions.  So that any more shift will no longer change it.
We will have to change some of signed and some of them as unsigned, so that there is no -1.
 
Ross,
 
The problem is that VARx are signed 32 bit numbers. So that shift a minus number then storing in VARx, it will be stored in a way to eventually reach to 0xFFFF.  
The easiest way is that you can check in PLC if VAR1 is -1, set that to your initial 2048, otherwise, you can let us know what would be reasonable solution, we can internally in firmware set the value for you.
Thanks.
 
Wayne, it's not completely that simple.
Once you get a "1" in the top bit, shifting right messes up too.
 
I agree, it's a sign bit thing. Any number >2^31 is treated as a 2's complement signed (negative) number, which means shifting it right is the same as dividing it by two, and dividing a negative number by 2 remains a negative number. Bitwise rotates should not do that. It should rotate the bits, unsigned.
 
I think "signed rotate" is actually a contradiction in terms :)
 
Ross,
 
Once you get '1' in top bit, rotating another will be -1, that is also 0xFFFFFFFF. At that value, rotate again will make no difference, since rotl or rotr has no clue few PLC command earlier that was 1.
We will experiment with it to see if we could allocate unsigned 32 bit space for rotating purpose. That could be done on WC32 easily. But on WC8, to get a few 32bit storage takes some experiment.  We will test them out and let you know.  For the time being, once VAR1 reached -1, your PLC code could set that to your desired default value.
 
There should be no need to allocate *additional* memory for it.
A rotate (or shift) should be a bitwise operation regardless. It applies to the 32 *BITS*, not to the "NUMBER".
 
Once you get a "1" in the top bit (2^31), ROTATING LEFT ONE BIT SHOULD YIELD +1 NOT -1
Ie, 0x80000000 becomes 0x00000001
 
Similarly, ROTATING right should see:
 
0x00000001
0x80000000
0x40000000
0x20000000
 
What seems to be happening is
 
0x00000001
0x80000000
0xC0000000
0xE0000000
0xF0000000
0xF8000000
 
Ie you're preserving the "sign bit" on right shift, and this is just plain wrong.
 
Ross,
 
It is the signed 32bit integer rotating caused problem.  We modified the code internally, so that during rotate, we save them into unsigned number internally then rotate.  That fixed problem.
You may download the new firmware and give that a try to see if that working for you:

For wc32 board only, download from this link:
http://www.cainetworks.com/support/download/wc32update040218.zip

Please update firmware, GUI code, then API code in sequence.

GUI source code is same as 4.02.14 level, if building your own GUI from older firmware, you would need to change custom GUI.
http://www.cainetworks.com/support/download/wc32guisrc040214.zip

 
Once again, thanks for reporting any problem, we really appreciate it!
 
Back
Top