3

Cでは、次のようなことをします。

char var = 1;

while(1)
{
  var = var << 1;
}

8回目の反復では、「<<」演算子は1をシフトアウトし、varは0になります。ビットシフトを維持するためにシフトを実行する必要があります。言い換えれば、私はこれが必要です:

初期-----00000001

1シフト目-00000010

2番目のシフト-00000100

3番目のシフト-00001000

4シフト-00010000

5シフト-00100000

6シフト-01000000

7シフト-10000000

8番目のシフト-00000001(8番目のシフトで自動的に再開します)

「<<」に相当するものはありますが、これを実現するためのものはありますか?

4

4 に答える 4

5

これは循環シフトとして知られていますが、Cは言語レベルでこの機能を提供していません。

プラットフォームにそのような命令がネイティブにあると仮定すると、これを自分で実装するか、インラインアセンブラルーチンに頼る必要があります。

例えば:

var = (var << 1) | (var >> 7);

(ただし、これは負signedの型に対して明確に定義されていないため、例をに変更する必要がありますunsigned char。)

于 2012-07-05T14:54:30.350 に答える
1

したがって、ビット回転、別名循環シフトを実行する必要があります。

#include <limits.h>   // Needed for CHAR_BIT

// positive numbits -> right rotate, negative numbits -> left rotate
#define ROTATE(type, var, numbits) ((numbits) >= 0 ? \
                                    (var) >> (numbits) | (var) << (CHAR_BIT * sizeof(type) - (numbits)) : \
                                    (var) << -(numbits) | (var) >> (CHAR_BIT * sizeof(type) + (numbits)))

サイズを()sizeof()のサイズの倍数として返し、aのビット数を示します(通常は8である必要はありません)が、ビット単位のサイズを示します。charsizeof(char) == 1CHAR_BITcharCHAR_BIT * sizeof(x)x

于 2012-07-05T15:09:42.267 に答える
1

はい、循環シフトを使用できます。(組み込みのC操作ではありませんが、x86 CPUのCPU命令です)

于 2012-07-05T14:55:14.457 に答える
0

これは循環シフトと呼ばれます。これを行うためのIntelx86アセンブリ命令がありますが、パフォーマンスが本当に本当に大きな問題でない限り、次のようなものを使用する方が良いでしょう。

int i = 0x42;
int by = 13;
int shifted = i << by | i >> ((sizeof(int) * 8) - by);

本当にパフォーマンスが必要な場合は、インラインアセンブリを使用して、命令を直接使用できます(おそらく、試してみるほどひどく必要だったことはありません)。

データ型のサイズよりも多くの場所でシフトする場合は、シフトオーバーしていないことを確認するために追加のチェックが必要になることに注意することも重要です。を使用by = 48すると、値0の受信がシフトする可能性がありますが、この動作はプラットフォーム固有(つまり、ペストのように回避するもの)である可能性があります。正しく思い出せば、一部のプラットフォームはこのマスキングを自動的に実行し、他のプラットフォームは実行しないためです。

于 2012-07-05T14:56:45.680 に答える