Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 14:56:14 UTC, burt wrote: On Saturday, 30 January 2021 at 14:41:59 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 14:40:49 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: [...] cast as uint and shift. cast the result as ubyte[4]. obiously, that works for n=4 with uint and n=8 for ulong, only. Yes I used to do this, but then I needed it for n > 8. You can try somethink like this: https://run.dlang.io/is/POQgnb import std.range : cycle, take, drop; import std.algorithm : copy; import std.stdio; version (LittleEndian) ubyte[n] rotateRight(size_t n)(ref const ubyte[n] array, uint rotation){ typeof(return) result; array[] .cycle() .drop(n - (rotation / 8) % n) .take(n) .copy(result[]); const ubyte bit_rotation = rotation % 8; enum ubyte full = 0b_; if(bit_rotation == 0) return result; ubyte next_prefix(const ubyte elm){ const ubyte suffix = (elm & ~(full << bit_rotation)); const ubyte prefix = cast(ubyte)(suffix << (8 - bit_rotation)); return prefix; } ubyte prefix = next_prefix(result[$-1]); foreach(ref ubyte elm; result[]){ const new_prefix = next_prefix(elm); elm = (elm >> bit_rotation) | prefix; prefix = new_prefix; } return result; } void main(){ ubyte[4] x = [ 0b00011000, 0b0011, 0b00010101, 0b0010, ]; writefln!"%(%8b,\n%)"(x.rotateRight(4)); }
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 14:56:14 UTC, burt wrote: On Saturday, 30 January 2021 at 14:41:59 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 14:40:49 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: [...] cast as uint and shift. cast the result as ubyte[4]. obiously, that works for n=4 with uint and n=8 for ulong, only. Yes I used to do this, but then I needed it for n > 8. As suggested in the other answer BitArray may be the best generic solution.
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 14:41:59 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 14:40:49 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: [...] cast as uint and shift. cast the result as ubyte[4]. obiously, that works for n=4 with uint and n=8 for ulong, only. Yes I used to do this, but then I needed it for n > 8.
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 14:17:06 UTC, Paul Backus wrote: On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: [...] Now I want to bit-rotate the array as if it is one big integer. You may find `std.bitmanip.BitArray` useful for this: http://phobos.dpldocs.info/std.bitmanip.BitArray.html Thank you, this is indeed what I am looking for! For future reference, this is how I implemented it: ```d ubyte[n] rotateRight(size_t n)(ubyte[n] x, uint rotation) { import std.bitmanip : BitArray; ubyte[n] x2; foreach (i, value; x) // have to swap because of endianness x2[n - 1 - i] = value; auto copy = x2; auto bitArray1 = BitArray(cast(void[]) x2[], n * 8); auto bitArray2 = BitArray(cast(void[]) copy[], n * 8); bitArray1 >>= rotation; bitArray2 <<= n * 8 - rotation; bitArray1 |= bitArray2; foreach (i, value; x2) // swap back x[n - 1 - i] = value; return x; } ubyte[4] x = [ 0b00011000, 0b0011, 0b00010101, 0b0010, ]; writefln!"%(%8b,\n%)"(x.rotateRight(4)); ```
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 14:40:49 UTC, Afgdr wrote: On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: I have a static array of `ubyte`s of arbitrary size: ```d ubyte[4] x = [ // in reality, ubyte[64] 0b1000, 0b0001, 0b00010101, 0b0010, ]; ``` Now I want to bit-rotate the array as if it is one big integer. So: ```d ubyte[n] rotateRight(size_t n)(ref const ubyte[n] array, uint rotation) { // ? } // same for rotateLeft ubyte[4] y = [ 0b1001, 0b0100, 0b, 0b10001010, ]; assert(x.rotateRight(9) == y); assert(y.rotateLeft(9) == x); ``` Any ideas how this could be achieved? I.e. what should go at the "?" for rotateRight and rotateLeft? cast as uint and shift. cast the result as ubyte[4]. obiously, that works for n=4 with uint and n=8 for ulong, only.
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: I have a static array of `ubyte`s of arbitrary size: ```d ubyte[4] x = [ // in reality, ubyte[64] 0b1000, 0b0001, 0b00010101, 0b0010, ]; ``` Now I want to bit-rotate the array as if it is one big integer. So: ```d ubyte[n] rotateRight(size_t n)(ref const ubyte[n] array, uint rotation) { // ? } // same for rotateLeft ubyte[4] y = [ 0b1001, 0b0100, 0b, 0b10001010, ]; assert(x.rotateRight(9) == y); assert(y.rotateLeft(9) == x); ``` Any ideas how this could be achieved? I.e. what should go at the "?" for rotateRight and rotateLeft? cast as uint and shift. cast the result as ubyte[4].
Re: Bit rotation question/challenge
On Saturday, 30 January 2021 at 13:30:49 UTC, burt wrote: I have a static array of `ubyte`s of arbitrary size: ```d ubyte[4] x = [ // in reality, ubyte[64] 0b1000, 0b0001, 0b00010101, 0b0010, ]; ``` Now I want to bit-rotate the array as if it is one big integer. You may find `std.bitmanip.BitArray` useful for this: http://phobos.dpldocs.info/std.bitmanip.BitArray.html
Bit rotation question/challenge
I have a static array of `ubyte`s of arbitrary size: ```d ubyte[4] x = [ // in reality, ubyte[64] 0b1000, 0b0001, 0b00010101, 0b0010, ]; ``` Now I want to bit-rotate the array as if it is one big integer. So: ```d ubyte[n] rotateRight(size_t n)(ref const ubyte[n] array, uint rotation) { // ? } // same for rotateLeft ubyte[4] y = [ 0b1001, 0b0100, 0b, 0b10001010, ]; assert(x.rotateRight(9) == y); assert(y.rotateLeft(9) == x); ``` Any ideas how this could be achieved? I.e. what should go at the "?" for rotateRight and rotateLeft?