2016-12-12 4 views
1

私はuint8_tの36バイトのデータの型キャスト配列を持っています。 ビットを配列全体に循環的にシフトしたい(右シフト)。 どうすればいいですか?例えば:配列内のビットごとの循環シフト

uint8_t arr[3] = {0x03, 0x44, 0x32} 

は1つのシフトの後、それは次のようになります。

arr[3] = {0x01, 0xa2, 0x19} 
+1

非循環シフトを実行する方法は知っていますか?そして、なぜ循環シフトの結果が余分なバイトを占めるのでしょうか? –

+0

右回りの回転とも呼ばれる右回りのシフトは、シーケンスの最下位ビットが最上位ビットに循環することを意味します。右に回転された1バイトの例0x03を使用すると、0x81になります。右にシフトされた同じ値が0x01であるところ。あなたはここに何を持っていますか? –

+0

@PeterCamilleri - 私はOPが配列全体のビットを回転させようとしていると思います。したがって、要素「n」の最下位ビットは要素「n + 1」の最高ビットになります。最後の要素の最下位ビットが最初の要素の最上位ビットになります。 – Paolo

答えて

0

次のコードで配列を循環シフトすることができます。それはほとんど自明であるとコメントされています。

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

ループ配列の各バイトを通じて。各バイトについて、まず低ビットをチェックし、それが設定されている場合はキャリーアウトフラグをセットする。次に、バイトを1つ右にシフトすることができます。

次のバイトについて上記を繰り返しますが、最初にキャリーインフラグをキャリーアウトフラグの現在の値に設定します。シフト後、キャリーインフラグをチェックし、セットされている場合は現在のバイトの上位ビットをセットします。あなたが配列の終わりに達するまで続けてください。最後にキャリーアウトフラグがセットされている場合は、最初のバイトの上位ビットをセットします。

+0

C言語を使ってキャリービットを作る方法を説明する必要があるかもしれません。実際、キャリービットがあると仮定できますか? –

+0

@ScottHunter "キャリーフラグ"だったはずです。編集されました。 – dbush

+1

キャリーフラグを最後の要素の下位ビットとして初期化し、最後に戻る必要はありません... – Persixty

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; 
    
関連する問題