Page 1 of 1
How are bitwise operators correctly used?
Posted: 30 Mar 2014 01:32
by electrofux
Hello,
i figured i could use bitwise operators to shift a stepnote (stepslider?) pattern around.
How do you use it? StepNote.x>>1 didn't do anything.
Cheers
electrofux
Re: How are bitwise operators correctly used?
Posted: 30 Mar 2014 02:40
by Macciza
Hi
Maybe do a web search on bitwise operators . . .
They do operations on the binary version of the numbers ie 1>>1 = 0. 1<<1=2.
Operating on an array it simply performs on each value
To shift / rotate an array is quite different
You could write your own function to take sub arrays and place them as needed
ie array = {1,0,0,0}
array = {subarray(array,3,1),subarray(array,0,3)
Of course use sizeof functions etc to the value needed
Does that help
MM
Re: How are bitwise operators correctly used?
Posted: 30 Mar 2014 14:23
by electrofux
Yeah, i did a search and found:
"If the variable ch contains the bit pattern 11100101, then ch >> 1 will give the output as 01110010"
On second look this doesnt shift and wrap around so it doesnt seem to bethat usefull for shifting StepNote arrays. Seems i misunderstood the concept and will rather go for your version.
But since << and >> are in the manual i was wondering how the syntax would be. If we have StepNote.x={1,1,1,0,0,1,0,1}, how would i use >> to get StepNote.x={0,1,1,1,0,0,1,0}?
StepNote.x>>1 or StepNote.x=StepNote.x>>1 didnt do anything. I was under the assumption that it works on the whole array as the Manual said:
"Bitwise operators allow operations on array patterns at the level of their individual elements". A short example would come in handy.
Re: How are bitwise operators correctly used?
Posted: 31 Mar 2014 10:28
by oldgearguy
electrofux wrote:Yeah, i did a search and found:
"If the variable ch contains the bit pattern 11100101, then ch >> 1 will give the output as 01110010"
On second look this doesnt shift and wrap around so it doesnt seem to bethat usefull for shifting StepNote arrays. Seems i misunderstood the concept and will rather go for your version.
But since << and >> are in the manual i was wondering how the syntax would be. If we have StepNote.x={1,1,1,0,0,1,0,1}, how would i use >> to get StepNote.x={0,1,1,1,0,0,1,0}?
StepNote.x>>1 or StepNote.x=StepNote.x>>1 didnt do anything. I was under the assumption that it works on the whole array as the Manual said:
"Bitwise operators allow operations on array patterns at the level of their individual elements". A short example would come in handy.
In other languages, they have separate shift and rotate operators. If you only have shift, you have to 'catch' the bit and stick it back on yourself. Just for completeness, I'll go over a couple points you already know and also add the rotate.
To isolate a bit involves 2 steps - masking off the other bits and shifting the target bit into place. Bits are counted/named from right to left.
So, if you have 8 bits: '01101011' and you wanted the 4th bit you have to mask and shift. The order doesn't really matter in isolated cases, but it does change your mask.
If we want to have a constant as a mask, I would shift first, then mask like this:
Code: Select all
isolate(data, position) {
decl myBit, bitmask=0x01;
myBit = (data >> (position - 1)) & bitmask;
return(myBit);
}
couple notes - I passed in the position as a human would understand it (fourth bit) and adjusted the number inside to start from zero just to make it easier for other programmers. Having to remember whether an arrary/operation is zero-based or one-based leads to all kinds of 'off by 1' bugs. Also, the bitmask is hardcoded because we're doing the shift work first. Finally, all bits that are shifted, 'fall to the ground' and are not saved.
to do a rotate, you need to save the bit(s) that fall off the end and stick them back on the other side. A side effect of shift is that the data is filled with zeros, so a simple logical OR operation will put them back. Here is the generic case. If you want a single bit rotated only, pull out the looping code and you don't have to pass in a rotate amount (always 1). I copied the parameter to a local variable just in case there's other things I might want to do with it. Also, I'm not exactly 100% sure how Lemur treats parameters and how they are passed (reference or value).
***Big assumption*** - the size of the data is 8 bits for this example!! Note the hardcoded 7. You need to shift back size-1 (I'd probably pass in size if I wanted it really generic). Also - this is just typed in stuff, I don't have an environment here to test it, so don't just drop this into production code and ship the template.
Code: Select all
rotate(data, amount) {
decl myBit, buf, i;
buf = data;
for (i=0; i<amount; i++) {
myBit = buf & 0x01;
buf = buf >> 1;
buf = buf | (myBit << 7);
}
return(buf);
}
Re: How are bitwise operators correctly used?
Posted: 31 Mar 2014 11:10
by Macciza
Ah ok slight misunderstanding there I think
That 'bit pattern' is the binary representation of a decimal number
So the comment from the manual is probably just meant to mean it operates on each element of an array.
Basically it does not operate on the array as whole as you were thinking.
So two options are available
1. Convert the array - as a bit pattern to decimal number - and then bit shift that number and convert back.
2. Simply shift the array itself around as 2 subarrays of itself.
Option 1 is not as difficult as it sounds but is a bit of overkill - an interesting elegant technical solution but without easy wrapping
Option 2 is far more straight forward as it is simply moves stuff around which is what you are doing and so it wraps naturally
Heres a script for shifting
shift(array, val) Manual Trigger
decl len = sizeof(array);
val = val % len;
if(val>0) array={subarray(array,len-val,val),subarray(array,0,len-val)};
if(val<0) array={subarray(array,abs(val),len-abs(val)),subarray(array,0,abs(val))};
return array;
Can tidy up something to show option 1 as well
Cheers
MM
Re: How are bitwise operators correctly used?
Posted: 01 Apr 2014 11:59
by electrofux
Macciza wrote:Ah ok slight misunderstanding there I think
That 'bit pattern' is the binary representation of a decimal number
So the comment from the manual is probably just meant to mean it operates on each element of an array.
Basically it does not operate on the array as whole as you were thinking.
So two options are available
1. Convert the array - as a bit pattern to decimal number - and then bit shift that number and convert back.
2. Simply shift the array itself around as 2 subarrays of itself.
Option 1 is not as difficult as it sounds but is a bit of overkill - an interesting elegant technical solution but without easy wrapping
Option 2 is far more straight forward as it is simply moves stuff around which is what you are doing and so it wraps naturally
Heres a script for shifting
shift(array, val) Manual Trigger
decl len = sizeof(array);
val = val % len;
if(val>0) array={subarray(array,len-val,val),subarray(array,0,len-val)};
if(val<0) array={subarray(array,abs(val),len-abs(val)),subarray(array,0,abs(val))};
return array;
Can tidy up something to show option 1 as well
Cheers
MM
Perfect thx. I just thought from the sound of it something like array>>1 would be sufficient but well, you explained it, it was a misunderstanding.
Re: How are bitwise operators correctly used?
Posted: 01 Apr 2014 13:19
by Macciza
No worries
But make sure you also go through and understand oldgearguys comments and explanations as well . . .
I'm not that good at it all but can understand and enjoy the elegance of the solutions most of the time . . .
I probably should try and use it a bit more where appropriate . .
Cheers all