実際のプロジェクトでビットシフトを使用する必要があったことはありますか?


83

実際のプログラミングプロジェクトでビットシフトを使用する必要があったことはありますか?ほとんどの(すべてではないにしても)高級言語にはシフト演算子が含まれていますが、実際にそれらを使用する必要があるのはいつですか?

回答:


58

私はまだハードウェアで浮動小数点をサポートしていないシステムのコードを書いています。これらのシステムでは、ほぼすべての演算にビットシフトが必要です。

また、ハッシュを生成するにはシフトが必要です。多項式の算術(CRC、リードソロモンコードが主流のアプリケーション)またはシフトも使用します。

ただし、シフトは便利で、ライターが意図したとおりに表現するために使用されます。必要に応じて、乗算を使用してすべてのビットシフトをエミュレートできますが、それを書くのは難しく、読みにくく、場合によっては遅くなります。

コンパイラーは、乗算をシフトに減らすことができるケースを検出します。


37

はい、私はそれらを何度も使用しました。ビットマスクが非常に一般的である組み込みハードウェアでは、ビットの調整が重要です。また、ゲームプログラミングでは、パフォーマンスの最後のすべてが必要な場合にも重要です。

編集:また、色深度の変更やRGB <-> BGRの変換など、ビットマップの操作によく使用します。


出向。私は多くの組み込みプログラミングを行っており、ビットシフトは一般的な操作です。
e.James 2009

RGB <-> BGR変換はこちら。
ニールN

25
  • 列挙型の適切なフラグ値を作成する(手動で1、2、4 ...と入力するのではなく)
  • ビットフィールドからのデータの解凍(多くのネットワークプロトコルはそれらを使用します)
  • Zカーブトラバーサル
  • パフォーマンスハック

そして、それらが使用されているとき、私は多くの場合を考えることができません。通常は逆です。特定の問題があり、ビット演算を使用すると最良の結果が得られることがわかります(通常はパフォーマンスの観点から-時間やスペース)。


たとえば、ASP.netのセッション状態のshort1つのintegerフィールドに2つのを格納し、2つの別々の値を読み取るためにセッションを読み取ってロックするオーバーヘッドなしに必要になる場合があります。また、セッションに2つの値を格納することによるメモリオーバーヘッドも節約されます。
David d C e Freitas 2011

15

私がいつもそれらを使用している場所の1つは、クロスプラットフォームアプリケーションの整数のエンディアンを転置するときです。また、2Dグラフィックスをブリットするときに、(他のビット操作演算子とともに)便利な場合もあります。


次に、EBCDIC文字セットのコンバーターを作成します。残念ながら、これは実際には高水準言語で低水準の作業を行っていますが、場合によっては必要です。
Michael Meadows


7

ビットシフトは高速です。これらは、除算およびモジュラス演算が行われるずっと前に、CPU命令セットに実装されていました。私たちの多くは、鉛筆と紙では簡単ですが、CPUでは使用できない算術演算にビットシフトを使用しています。

例えば:

  • 私は、大きなコンポジットを素因数分解するプロジェクトにビットシフトを使用しました。
  • また、任意の大きさの整数の平方根と立方根を見つけるためにビットシフトを使用しました。

立方体または平方根を見つけるためにそれをどのように使用するかの例を投稿していただけますか?私はこれがどのように行われるのか少しわかりません。
xsmael 2015年

5

はい、それでも必要です。

たとえば私の仕事では、シリアルポートCOMxを介してPLCと通信するためのソフトウェアを開発しています。バイト内のビットを処理する必要があります。左/右シフトを使用し、論理演算子OR、XOR、ANDを毎日使用します。

たとえば、バイトのビット3(右から左)をオンにする必要があるとします。

これを行う方がはるかに効率的です。

Byte B;

B := B XOR 4;

の代わりに:

Byte B = 0;
String s;  // 0 based index

s = ConvertToBinary (B);
s[5] = "1";
B := ConvertToDecimal (s);

よろしく。


1
4がビット3に関連する理由(右から左へ)を追加することをお勧めします
HCP 2011年

1
なぜs [5]?S [2]ではないですか?
iamIC 2014年

1
B:= B XOR 4; この場合、特定のビットをオンにするには、ORだけではいけませんか?XORは切り替えに使用されませんか?stackoverflow.com/questions/47981/…–
Hari

4

私がアセンブリ言語で書いたとき、私のコードはビットシフトとマスキングでいっぱいでした。

Cでもかなりの量でしたか。

JavaScriptやサーバー言語ではあまり行っていません。

おそらく、最近の最良の使用法は、1と0で表されるブール値のパックされた配列をステップスルーすることです。以前は常に左シフトしてアセンブリの符号ビットをチェックしていましたが、高級言語では値と比較します。

たとえば、8ビットの場合、「if(a> 127){...}」で最上位ビットをチェックします。次に、左シフト(または2を掛ける)、127で「and」を実行(または最後のビットが設定されている場合は256の減算を実行)して、もう一度実行します。


3

ビットマップのビットが圧縮される画像圧縮/解凍でそれらをよく使用しました。http://en.wikipedia.org/wiki/Huffman_codingを使用すると、圧縮されるものはさまざまな数のビットで構成されます(すべてがバイト整列されているわけではありません)。したがって、エンコードまたはデコードするときにビットシフトする必要があります。 。


3

たとえば、C、C ++などの言語での暗号化メソッドの実装。バイナリファイル、圧縮アルゴリズム、論理リスト操作-ビット演算は常に適切です=)


3

ビットシフトは高水準プログラミングの問題を解決しませんが、低レベルの問題を解決しなければならない場合があり、それを行うためにCで別のライブラリを作成する必要がないので便利です。それが最もよく使われるのは私の推測です。

私はこれをEBCDIC文字セットコンバーターのエンコーダーの作成に個人的に使用しました。


3

はい、あります。ご想像のとおり、デバイスのドライバの開発など、低レベルのプログラミングで見つかる可能性が最も高いです。しかし、私は医療機器からデータを受信するWebサービスを開発する必要があるC#プロジェクトに取り組みました。デバイスに保存されたすべてのバイナリデータはSOAPパケットにエンコードされましたが、バイナリデータは圧縮されてエンコードされました。したがって、それを解凍するには、たくさんのビット操作を行う必要があります。さらに、有用な情報を解析するには、多くのビットシフトを行う必要があります。たとえば、デバイスのシリアル番号は2番目のバイトの下半分などです。また、.NET(C#)の世界で、ビットマスキングとフラグ属性を使用している人もいますが、個人的にはそうする衝動はありませんでした。


3

うん。私は前に暗号化アルゴリズムを書かなければなりません、そしてそれは間違いなくそれらを使用します。

また、ステータスを追跡するために整数などを使用する場合にも役立ちます。



3

私はコンピュータ周辺機器メーカーで働いています。私は、ほぼ毎日、ビットシフトを使用するコードに遭遇し、実装する必要がありました。


3

ビットシフトは、オンラインゲームのプロトコルを解読する際によく使用されます。プロトコルは可能な限り小さな帯域幅を使用するように設計されているため、サーバー上のプレーヤーの数や名前などをint32で送信する代わりに、すべての情報が可能な限り少ないバイトにパックされます。最近ではほとんどの人がブロードバンドを使用しているので、それは本当に必要ではありませんが、元々設計されたとき、人々はゲームに56kモデムを使用していたので、すべてのビットが重要でした。

この最も顕著な例は、Valveのマルチプレイヤーゲーム、特にCounter-Strike、Counter-StrikeSourceにあります。Quake3プロトコルも同じですが、Unrealはそれほどスリムではありません。

これが例です(.NET 1.1)

string data = Encoding.Default.GetString(receive);

if ( data != "" )
{
    // If first byte is 254 then we have multiple packets
    if ( (byte) data[0] == 254 )
    {
        // High order contains count, low order index
        packetCount = ((byte) data[8]) & 15; // indexed from 0
        packetIndex = ((byte) data[8]) >> 4;
        packetCount -= 1;

        packets[packetIndex] = data.Remove(0,9);
    }
    else
    {
        packets[0] = data;

    }
}

もちろん、これを実際のプロジェクトと見なすか、単なる趣味(C#)と見なすかはあなた次第です。


2

高速フーリエ変換— FFTとそのCooley-Tukey手法では、ビットシフト演算を使用する必要があります。


独自のFFTルーチンをローリングしますか?tut-tut :)私も自分でやったことを認めます-アルゴリズムを深く理解するのに最適です。
マーティ

2

与えられた数以上の2の最も近い累乗を見つけます。

1 << (int)(ceil(log2(given)))

任意のテクスチャサイズをサポートしないハードウェアでのテクスチャリングに必要です。


1

はい、MPEG2-2トランスポートストリームパーサーで使用しました。それはより簡単で読みやすくなりました。


1

DVDディスク上の.ifoファイルを解析するプログラムを作成する必要がありました。これらは、ディスク上のタイトル、チャプター、メニューなどの数を説明するファイルです。それらは、すべてのサイズと配置のパックされたビットで構成されています。多くのバイナリ形式で同様のビットシフトが必要だと思います。


1

プロパティパラメータとして複数のフラグが使用されたときにビット単位の演算子が使用されるのを見てきました。たとえば、番号4 = 1 0 0は、3つのフラグの1つが設定されていることを意味します。これはパブリックAPIには適していませんが、ビットのチェックが高速であるため、特別な場合に処理を高速化できます。



1

私はゲームでそれらを使用して、データカードに保存するために一連のフラグを1バイト/文字にパックしました。ロック解除可能なアイテムのステータスを保存するなど。最近の要件はそれほど多くありませんが、作業を節約できます。


1

モニターのEDIDデータを読み取らなければならない組み込みシステムのプロジェクトで使用しています。EDIDの一部のデータは、次のようにエンコードされます。

バイト#3:
水平ブランキング-下位8ビット
バイト#4:
下位ニブル:水平ブランキング-上位4ビット
上位ニブル:その他

1

はい、JavaアプリケーションとC#アプリケーションの間でバイナリ通信を実行する場合、1つはビッグエンディアンのバイト順序で、もう1つはリトルエンディアンです(必ずしもこの順序である必要はありません)。異なるバイト順序の数値を読み取ることができるInputStreamクラスを作成し、それが機能するためにバイトシフトを使用しました。

longの4バイトに4つのshortを入れたい場合も、バイトシフトを使用する場合があります。私は何年も前にそれをしたと思います...


1

もう1つの非常に一般的なことは、バイトの上位ニブルを抽出するときに4ビットシフトを実行することです。

#define HIGH_NIBBLE(byte) (((byte) >> 4) & 0x0F)
#define LOW_NIBBLE(byte)  ( (byte)       & 0x0F)

ハードウェアを直接使用していて、任意のビットマッピングを使用してレジスタから直接データを取得する場合は特にそうです。
クリス

0

「低レベル」の機器、eqデジタルイーサネット-IOボックスまたはPLCと通信する場合も、ビットシフトが必要です。これらは通常、個々の入力/出力値をバイトにパックします。



0

はい、いつもです。32ビット整数との間で3空間座標をパックおよびアンパックするためのこれらのマクロのように:

#define Top_Code(a, b, c)           ((((a) + x) << 20) | (((b) + y) << 10) | ((c) + z))                           
#define From_Top_Code(a, b, c, f)   (a = (((f) >>> 20) - x), b = ((((f) & 0xffc00) >>> 10) - y), c = (((f) & 0x3ff) - z))        

0

私はかつて(何年も前に)、ExcelOper構造を使用してExcelスプレッドシートを作成するプロジェクトの出力ルーチンを作成しました。これは、大量のビットをいじる必要のあるバイナリファイルフォルマントでした。次のリンクは、オペラ構造の風味与えSafariの書籍

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.