2

私はこのプログラミング プロジェクトに取り組んでおり、その一部は、2 ビットごとに切り替わるビット演算子のみを使用して関数を作成することです。これを実現する櫛のようなアルゴリズムを思いつきましたが、符号なしの数値に対してのみ機能します。符号付きの数値でも機能させる方法はありますか? 私はこれに完全に困惑しています。私がこれまでに持っているものは次のとおりです。

        // Mask 1 - For odd bits
    int a1 = 0xAA; a1 <<= 24;
    int a2 = 0xAA; a2 <<= 16;
    int a3 = 0xAA; a3 <<= 8;
    int a4 = 0xAA;
    int mask1 = a1 | a2 | a3 | a4;

    // Mask 2 - For even bits
    int b1 = 0x55; b1 <<= 24;
    int b2 = 0x55; b2 <<= 16;
    int b3 = 0x55; b3 <<= 8;
    int b4 = 0x55;
    int mask2 = b1 | b2 | b3 | b4;

    // Mask Results
    int odd = x & mask1;
    int even = x & mask2;

    int newNum = (odd >> 1) | (even << 1);

    return newNum;

変数を一緒に論理和することによってマスクを手動で作成するのは、使用できる唯一の定数が 0x00 ~ 0xFF の間であるためです。

4

4 に答える 4

3

問題は、odd >> 1符号が負の数で拡張されることです。and重複したビットを削除するには、別の操作を行うだけです。

int newNum = ((odd >> 1) & mask2) | (even << 1);
于 2013-09-18T19:05:48.450 に答える
2

演算子を最小化し、符号拡張の問題に気付くと、次のようになります。

int odd = 0x55;
odd |= odd << 8;
odd |= odd << 16;

int newnum =   ((x & odd) << 1 )  // This is (sort of well defined)
             | ((x >> 1) & odd);  // this handles the sign extension without
                                  // additional & -operations

ただし、ビット調整は通常、符号なし整数にのみ適用する必要があります。

于 2013-09-18T19:28:43.163 に答える
0

符号付きの数値を右シフトすると、符号も拡張されます。これは符号拡張として知られています。通常、ビット シフトを扱う場合は、符号なしの数値を使用します。

于 2013-09-18T19:08:46.973 に答える
0

一度に 1 バイトずつ処理することにより、定数の使用を最小限に抑えます。

unsigned char* byte_p;
unsigned char byte;
int ii;
byte_p = &x;   
for(ii=0; ii<4; ii++) {
  byte = *byte_p;
  *byte_p = ((byte & 0xAA)>>1) | ((byte & 0x55) << 1);
  byte_p++;
}     

操作を最小限に抑え、0x00との間の定数を維持する0xFF:

unsigned int comb = (0xAA << 8) + 0xAA;
comb += comb<<16;
newNum = ((x & comb) >> 1) | ((x & (comb >> 1)) << 1);

10回の操作。

上記のコメントを見て、@akisuihkonen が行った提案のいくつかを (多かれ少なかれ) 実装していることに気付きました。したがって、これを帽子のヒントと考えてください。

于 2013-09-18T19:08:56.580 に答える