私はuint8_t
の36バイトのデータの型キャスト配列を持っています。 ビットを配列全体に循環的にシフトしたい(右シフト)。 どうすればいいですか?例えば:配列内のビットごとの循環シフト
uint8_t arr[3] = {0x03, 0x44, 0x32}
は1つのシフトの後、それは次のようになります。
arr[3] = {0x01, 0xa2, 0x19}
私はuint8_t
の36バイトのデータの型キャスト配列を持っています。 ビットを配列全体に循環的にシフトしたい(右シフト)。 どうすればいいですか?例えば:配列内のビットごとの循環シフト
uint8_t arr[3] = {0x03, 0x44, 0x32}
は1つのシフトの後、それは次のようになります。
arr[3] = {0x01, 0xa2, 0x19}
次のコードで配列を循環シフトすることができます。それはほとんど自明であるとコメントされています。
int main()
{
uint8_t arr[3] = {0x03, 0x44, 0x32};
int i,
l;
uint8_t savedCarry,
carry;
// let `l` be the size (nr. of elements) of the array
l = 3;
// this will cause the array bit shift to be circular
// by taking the "carry" bit (lowest bit) from the last element of the array
// this "carry" bit will be used on the first element in the `for` loop
carry = arr[ l - 1 ] & 1;
// loop trought the array applying bit shift
for(i = 0; i < 3; i++)
{
savedCarry = arr[i] & 1; // save the lowest bit
arr[i] = arr[i] >> 1; // right shift
if(carry)
{
arr[i] |= (uint8_t) 0x80; // the lowest bit of the previuos element becomes the highest bit of the current one
}
carry = savedCarry; // the lowest bit of this element will become the highest of the next one
}
// display hex output
for(i = 0; i < 3; i++)
{
printf("0x%02x\n", arr[i]);
}
return(0);
}
ウィル出力
0x01
0xa2
0x19
注あなたは最下位ビットを失う値を右シフトしています。そのため、操作の前に最下位ビットがsavedCarry
に保存されます。
for
の最後までsavedCarry
は次の配列値(次の繰り返し時)の最も高いビットを設定するcarry
にコピーされます。
ループ配列の各バイトを通じて。各バイトについて、まず低ビットをチェックし、それが設定されている場合はキャリーアウトフラグをセットする。次に、バイトを1つ右にシフトすることができます。
次のバイトについて上記を繰り返しますが、最初にキャリーインフラグをキャリーアウトフラグの現在の値に設定します。シフト後、キャリーインフラグをチェックし、セットされている場合は現在のバイトの上位ビットをセットします。あなたが配列の終わりに達するまで続けてください。最後にキャリーアウトフラグがセットされている場合は、最初のバイトの上位ビットをセットします。
配列インデックスが0
からN - 1
に行くと仮定すると、これを実行するための1つの方法は次のようになります。
は、最後の要素の最後のビットを保存します。これは、円最初の要素をキャリーとして追加するために使用されるであろう。1
からN - 1
から各素子i
について
uint8_t circular_carry = (arr[N - 1] & 1) << 7;
、右側の素子(arr[i] >> 1
)をシフト、及び、前の要素の最下位ビットをセットその最高の(すなわち8)ビット((arr[i - 1] & 1) << 7
):
int i;
for(i = N - 1; i > 0; i--) {
arr[i] >>= 1; // Right shift the (i)th byte
arr[i] |= (arr[i - 1] & 1) << 7; // Carry from the previous digit
}
右シフトし、最初の要素にcircular_carry
を追加します。
arr[0] >>= 1;
arr[0] += circular_carry;
非循環シフトを実行する方法は知っていますか?そして、なぜ循環シフトの結果が余分なバイトを占めるのでしょうか? –
右回りの回転とも呼ばれる右回りのシフトは、シーケンスの最下位ビットが最上位ビットに循環することを意味します。右に回転された1バイトの例0x03を使用すると、0x81になります。右にシフトされた同じ値が0x01であるところ。あなたはここに何を持っていますか? –
@PeterCamilleri - 私はOPが配列全体のビットを回転させようとしていると思います。したがって、要素「n」の最下位ビットは要素「n + 1」の最高ビットになります。最後の要素の最下位ビットが最初の要素の最上位ビットになります。 – Paolo