Circular shift
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Circular shift
Hi
I'm looking for a way to perform circular shift operations in LiveCode, like can be done in the C language using the bitwise operators << and >>. I could find only these four bitwise operators in the LC dictionary: bitAnd, bitOr, bitXor, and bitNot. Can someone point me in the right direction?
Gerrie
I'm looking for a way to perform circular shift operations in LiveCode, like can be done in the C language using the bitwise operators << and >>. I could find only these four bitwise operators in the LC dictionary: bitAnd, bitOr, bitXor, and bitNot. Can someone point me in the right direction?
Gerrie
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
-
- VIP Livecode Opensource Backer
- Posts: 9647
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Circular shift
Do you mean something like this, if you had, say, the string "A,B,C,D,E" and wanted "B,C,D,E,A"?
You could, assuming that you have a string in a field 1 and the comma is the item delimiter
You can always pass the delimiter as well, so that even lines and paragraphs could be rotated, or nothing, so that individual chars can be rotated.
But is this what you were looking for?
Craig Newman
You could, assuming that you have a string in a field 1 and the comma is the item delimiter
Code: Select all
on mouseUp
answer circular(fld 1,"right")
end mouseUp
function circular data,direction
if direction = "right" then
put comma & item 1 of data after data
delete item 1 of data
else
put the last item of data & comma before data
delete last item of data
end if
return data
end circular
But is this what you were looking for?
Craig Newman
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
Hello Craig
Yes I want to do something like that, only it needs to be a bitwise rotation of the individual bits of a 32-bit register, e.g. the number 1234 becomes the number 4644 if you rotate the bits left by 1 position.
edit: sorry, my example is 12-bit integer, not a 32-bit integer
Yes I want to do something like that, only it needs to be a bitwise rotation of the individual bits of a 32-bit register, e.g. the number 1234 becomes the number 4644 if you rotate the bits left by 1 position.
edit: sorry, my example is 12-bit integer, not a 32-bit integer
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
-
- VIP Livecode Opensource Backer
- Posts: 9647
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Circular shift
Hi.
Hermann will soon jump all over this. But before he does, please explain how you get 4644 from 1234.
Changing those values to base 2, and then rotating, does not do that, so i am on the wrong track.
Craig
Hermann will soon jump all over this. But before he does, please explain how you get 4644 from 1234.
Changing those values to base 2, and then rotating, does not do that, so i am on the wrong track.
Craig
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
Sorry, my bad!! I used a programmers' calculator to manually do the bit rotation and then afterwards read the OCT value off the screen instead of the decimal value! Sorry!
The number 1234 actually becomes 2468 after rotating the bits left by 1 position.
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
-
- VIP Livecode Opensource Backer
- Posts: 9647
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Circular shift
Ah.
But still not getting it.
Rotating the base 2 value of "1234" ("10011010010") gives "00110100101" which in base 10 is 421.Or if you rotate the other way, 617.
In order to get 2468 from 1234 (double the value), you must double the base 2 string, which requires that you add a "0" to the right side of the string itself. This is not rotating anything, merely doing arithmetic in base 2.
So?
Craig
But still not getting it.
Rotating the base 2 value of "1234" ("10011010010") gives "00110100101" which in base 10 is 421.Or if you rotate the other way, 617.
In order to get 2468 from 1234 (double the value), you must double the base 2 string, which requires that you add a "0" to the right side of the string itself. This is not rotating anything, merely doing arithmetic in base 2.
So?
Craig
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
Yes, you are correct, that is if you're working with 11 bits. If we were to represent the number as a 32-bit register, the bits would be "00000000000000000000010011010010", right? And then rotating the bits left by 1 position would take one "0" from the left and add it on the right. Or at least that's what I would expect.dunbarx wrote: ↑Sun Dec 16, 2018 10:24 pmAh.
But still not getting it.
Rotating the base 2 value of "1234" ("10011010010") gives "00110100101" which in base 10 is 421.Or if you rotate the other way, 617.
In order to get 2468 from 1234 (double the value), you must double the base 2 string, which requires that you add a "0" to the right side of the string itself. This is not rotating anything, merely doing arithmetic in base 2.
So?
Craig
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
-
- VIP Livecode Opensource Backer
- Posts: 9647
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Circular shift
Ah, again.
So typically, does a base 2 rotation ignore "leading" zeros?
If I wanted three eggs over easy, I might order "0003" eggs, and if the waiter either had a sense of humor or understood the math I was foisting on him, I would get an eatable breakfast.
In what sense does the rotation operation work in the register? What does the rotated value have to do with the original; what purpose does it serve? It cannot, with leading significant zeros, ever devolve to an actual value. It might, of course, perform other string-like tasks.
I have done that sort of thing with the outputs of an electronic lighting controller. I inverted binary strings, rotated them with their leading zeros just as you are asking to do, etc. to create visual effects. But in all those instances, there was never any relationship with an actual number.
Craig
So typically, does a base 2 rotation ignore "leading" zeros?
If I wanted three eggs over easy, I might order "0003" eggs, and if the waiter either had a sense of humor or understood the math I was foisting on him, I would get an eatable breakfast.
In what sense does the rotation operation work in the register? What does the rotated value have to do with the original; what purpose does it serve? It cannot, with leading significant zeros, ever devolve to an actual value. It might, of course, perform other string-like tasks.
I have done that sort of thing with the outputs of an electronic lighting controller. I inverted binary strings, rotated them with their leading zeros just as you are asking to do, etc. to create visual effects. But in all those instances, there was never any relationship with an actual number.
Craig
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
I don't know, I haven't done it before in any programming language.So typically, does a base 2 rotation ignore "leading" zeros?
HeheheIf I wanted three eggs over easy, I might order "0003" eggs, and if the waiter either had a sense of humor or understood the math I was foisting on him, I would get an eatable breakfast.
I can't think of many use cases myself. In fact, I've only ever seen one use case, which is what I'm looking to use it for -- cryptography.In what sense does the rotation operation work in the register? What does the rotated value have to do with the original; what purpose does it serve? It cannot, with leading significant zeros, ever devolve to an actual value. It might, of course, perform other string-like tasks.
I have done that sort of thing with the outputs of an electronic lighting controller. I inverted binary strings, rotated them with their leading zeros just as you are asking to do, etc. to create visual effects. But in all those instances, there was never any relationship with an actual number.
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
Re: Circular shift
About 30 million years ago I cut a couple of teeth and gnashed some gums on Z80 assembler with 8 bit registers. It was a very common process to shift left, shift right, rotate left or rotate right, for a variety of reasons but they were ubiquitous operations. The bit that was rotated or shifted off the end was typically / often copied to a parity bit, or the rotation was sometimes over the 9 bits of the register plus parity bit. I can't remember any of the purposes, but it did make sense at the time.
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
Here's what I've got working.
If only LC had a bitwise operator that could do the same as << and >> in C, then the above code could be reduced to only 5 lines.
Code: Select all
function rotateBits pNumber, pBitLength, pPositions, pDirection
local tBase2, tBase2new, tNumLeadingBits
put baseConvert(pNumber, 10, 2) into tBase2
put pBitLength - length(tBase2) into tNumLeadingBits
repeat tNumLeadingBits times
put "0" before tBase2
end repeat
if pDirection is "right" then
put (char (pBitLength +1 - pPositions) to -1 of tBase2) & (char 1 to (pBitLength - pPositions) of tBase2) into tBase2new
else
put (char pPositions +1 to -1 of tBase2) & (char 1 to pPositions of tBase2) into tBase2new
end if
return baseConvert(tBase2new, 2, 10)
end rotateBits
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Circular shift
As you are comparing your pure LC Script solution to the 32bit C operators:
The browser widget belongs to LC, so we have, besides *2^pPosition and div 2^pPosition, also the following possibility.
See for the javaScript operators https://developer.mozilla.org/en-US/doc ... _Operators
An application (that creates widget "shift" if not yet present):
The browser widget belongs to LC, so we have, besides *2^pPosition and div 2^pPosition, also the following possibility.
Code: Select all
function rotateBits pN, pP, pD -- 32bit numbers only
if pD is "L" then put "<<" into op -- signed left shift
else put ">>>" into op -- unsigned right shift
do "liveCode.JS(" &value(pN)&op&value(pP)& ")" in widget "shift"
wait 0 millisecs with messages; return the theResult of widget "shift"
end rotateBits
An application (that creates widget "shift" if not yet present):
Code: Select all
on mouseUp b
if there is no widget "shift" then
create widget "shift" as "com.livecode.widget.browser"
set script of widget "shift" to "on JS v; set theResult of me to v; end JS"
set javascriptHandlers of widget "shift" to "JS"
end if
-- yields 256,1024:
put rotateBits(2^8,sin(0),"R") &comma& rotateBits(2^8,1+1,"L")
end mouseUp
shiftLock happens
-
- VIP Livecode Opensource Backer
- Posts: 9647
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Circular shift
Hello, Hermann.
Just curious, why are you using explicit terms such as "sin(0)" or "1+1" as parameters?
In switch statements, sometimes if I have a "default" case, that is, after all conditional cases have been handled but there still remain all the other possibilities, I will have as the lastMost case something like:
case 3 = 3
...
That seems to always fire.
Is that sort of what you are doing here?
Craig
Just curious, why are you using explicit terms such as "sin(0)" or "1+1" as parameters?
In switch statements, sometimes if I have a "default" case, that is, after all conditional cases have been handled but there still remain all the other possibilities, I will have as the lastMost case something like:
case 3 = 3
...
That seems to always fire.
Is that sort of what you are doing here?
Craig
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
Re: Circular shift
Hi Craig.
This usually reduces the complain about missing "C-features" in LiveCode.
By the way: LC Builder has built-in BitwiseShiftLeft and BitwiseShiftRight operators.
Because my above 5 lines function has evaluating parameter expressions included.why are you using explicit terms such as "sin(0)" or "1+1" as parameters?
This usually reduces the complain about missing "C-features" in LiveCode.
By the way: LC Builder has built-in BitwiseShiftLeft and BitwiseShiftRight operators.
shiftLock happens
-
- Livecode Opensource Backer
- Posts: 132
- Joined: Mon Jan 14, 2013 3:37 pm
Re: Circular shift
Wow, thanks Hermann![-hh] wrote: ↑Mon Dec 17, 2018 3:39 pmAs you are comparing your pure LC Script solution to the 32bit C operators:
The browser widget belongs to LC, so we have, besides *2^pPosition and div 2^pPosition, also the following possibility.
See for the javaScript operators https://developer.mozilla.org/en-US/doc ... _OperatorsCode: Select all
function rotateBits pN, pP, pD -- 32bit numbers only if pD is "L" then put "<<" into op -- signed left shift else put ">>>" into op -- unsigned right shift do "liveCode.JS(" &value(pN)&op&value(pP)& ")" in widget "shift" wait 0 millisecs with messages; return the theResult of widget "shift" end rotateBits
An application (that creates widget "shift" if not yet present):
Code: Select all
on mouseUp b if there is no widget "shift" then create widget "shift" as "com.livecode.widget.browser" set script of widget "shift" to "on JS v; set theResult of me to v; end JS" set javascriptHandlers of widget "shift" to "JS" end if -- yields 256,1024: put rotateBits(2^8,sin(0),"R") &comma& rotateBits(2^8,1+1,"L") end mouseUp
I now only need it to actually rotate the bits, not just shift them while discarding the bits that were shifted out. One has to actually combine the the two operators to perform a rotation.
Modifying your rotateBits function a bit, I think this would do it:
Code: Select all
function rotateBits pN, pP, pD -- 32bit numbers only
if pD is "L" then
do "liveCode.JS((" & value(pN) & "<<" & value(pP) & ") | (" & value(pN) & ">>>" & value(32 - pP) & "))" in widget "shift" -- left rotate
else
do "liveCode.JS((" & value(pN) & ">>" & value(pP) & ") | (" & value(pN) & "<<" & value(32 - pP) & "))" in widget "shift" -- rotate right
end if; wait 0 millisecs with messages; return the theResult of widget "shift"
end rotateBits
Thank you so much, Hermann! You've impressed, as usual.
010100000110010101100001011000110110010100111101010011000110111101110110011001010010101101010100011100100111010101110100011010000010101101001010011101010111001101110100011010010110001101100101