Re: Bit rotation question/challenge

2021-01-30 Thread vitamin via Digitalmars-d-learn

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

2021-01-30 Thread Afgdr via Digitalmars-d-learn

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

2021-01-30 Thread burt via Digitalmars-d-learn

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

2021-01-30 Thread burt via Digitalmars-d-learn

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

2021-01-30 Thread Afgdr via Digitalmars-d-learn

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

2021-01-30 Thread Afgdr via Digitalmars-d-learn

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

2021-01-30 Thread Paul Backus via Digitalmars-d-learn

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

2021-01-30 Thread burt via Digitalmars-d-learn

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?