## digitalmars.D.learn - Bit rotation question/challenge

• burt (29/29) Jan 30 I have a static array of `ubyte`s of arbitrary size:
• Paul Backus (3/13) Jan 30 You may find `std.bitmanip.BitArray` useful for this:
• burt (28/34) Jan 30 Thank you, this is indeed what I am looking for!
• Afgdr (2/31) Jan 30 cast as uint and shift. cast the result as ubyte.
• Afgdr (2/38) Jan 30 obiously, that works for n=4 with uint and n=8 for ulong, only.
• burt (2/8) Jan 30 Yes I used to do this, but then I needed it for n > 8.
• Afgdr (3/12) Jan 30 As suggested in the other answer BitArray may be the best generic
• vitamin (42/51) Jan 30 You can try somethink like this:
```I have a static array of `ubyte`s of arbitrary size:

```d
ubyte x = [ // in reality, ubyte
0b00001000,
0b00000001,
0b00010101,
0b11110010,
];
```

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 y = [
0b11111001,
0b00000100,
0b00000000,
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?
```
Jan 30
```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 x = [ // in reality, ubyte
0b00001000,
0b00000001,
0b00010101,
0b11110010,
];
```

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
```
Jan 30
```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 x = [
0b00011000,
0b00100001,
0b00010101,
0b11110010,
];
writefln!"%(%8b,\n%)"(x.rotateRight(4));
```
```
Jan 30
```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 x = [ // in reality, ubyte
0b00001000,
0b00000001,
0b00010101,
0b11110010,
];
```

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 y = [
0b11111001,
0b00000100,
0b00000000,
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.
```
Jan 30
```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 x = [ // in reality, ubyte
0b00001000,
0b00000001,
0b00010101,
0b11110010,
];
```

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 y = [
0b11111001,
0b00000100,
0b00000000,
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.

obiously, that works for n=4 with uint and n=8 for ulong, only.
```
Jan 30
```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.

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.
```
Jan 30
```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.

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.
```
Jan 30    vitamin <vit vit.vit> writes:
```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.

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 = 0b1111_1111;

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 x = [
0b00011000,
0b00100001,
0b00010101,
0b11110010,
];

writefln!"%(%8b,\n%)"(x.rotateRight(4));
}
```
Jan 30