## 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[4].
• 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[4] x = [ // in reality, ubyte[64]
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[4] 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
Paul Backus <snarwin gmail.com> writes:
```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]
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[4] x = [
0b00011000,
0b00100001,
0b00010101,
0b11110010,
];
writefln!"%(%8b,\n%)"(x.rotateRight(4));
```
```
Jan 30
Afgdr <zerzre.rertert gmx.com> writes:
```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]
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[4] 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[4].
```
Jan 30
Afgdr <zerzre.rertert gmx.com> writes:
```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]
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[4] 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[4].

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[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.
```
Jan 30
Afgdr <zerzre.rertert gmx.com> 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[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.
```
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[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 = 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[4] x = [
0b00011000,
0b00100001,
0b00010101,
0b11110010,
];

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