実際のプログラミングプロジェクトでビットシフトを使用する必要があったことはありますか?ほとんどの(すべてではないにしても)高級言語にはシフト演算子が含まれていますが、実際にそれらを使用する必要があるのはいつですか?
回答:
私はまだハードウェアで浮動小数点をサポートしていないシステムのコードを書いています。これらのシステムでは、ほぼすべての演算にビットシフトが必要です。
また、ハッシュを生成するにはシフトが必要です。多項式の算術(CRC、リードソロモンコードが主流のアプリケーション)またはシフトも使用します。
ただし、シフトは便利で、ライターが意図したとおりに表現するために使用されます。必要に応じて、乗算を使用してすべてのビットシフトをエミュレートできますが、それを書くのは難しく、読みにくく、場合によっては遅くなります。
コンパイラーは、乗算をシフトに減らすことができるケースを検出します。
そして、それらが使用されているとき、私は多くの場合を考えることができません。通常は逆です。特定の問題があり、ビット演算を使用すると最良の結果が得られることがわかります(通常はパフォーマンスの観点から-時間やスペース)。
short
1つのint
egerフィールドに2つのを格納し、2つの別々の値を読み取るためにセッションを読み取ってロックするオーバーヘッドなしに必要になる場合があります。また、セッションに2つの値を格納することによるメモリオーバーヘッドも節約されます。
私がいつもそれらを使用している場所の1つは、クロスプラットフォームアプリケーションの整数のエンディアンを転置するときです。また、2Dグラフィックスをブリットするときに、(他のビット操作演算子とともに)便利な場合もあります。
ビットシフトは高速です。これらは、除算およびモジュラス演算が行われるずっと前に、CPU命令セットに実装されていました。私たちの多くは、鉛筆と紙では簡単ですが、CPUでは使用できない算術演算にビットシフトを使用しています。
例えば:
はい、それでも必要です。
たとえば私の仕事では、シリアルポート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);
よろしく。
私がアセンブリ言語で書いたとき、私のコードはビットシフトとマスキングでいっぱいでした。
Cでもかなりの量でしたか。
JavaScriptやサーバー言語ではあまり行っていません。
おそらく、最近の最良の使用法は、1と0で表されるブール値のパックされた配列をステップスルーすることです。以前は常に左シフトしてアセンブリの符号ビットをチェックしていましたが、高級言語では値と比較します。
たとえば、8ビットの場合、「if(a> 127){...}」で最上位ビットをチェックします。次に、左シフト(または2を掛ける)、127で「and」を実行(または最後のビットが設定されている場合は256の減算を実行)して、もう一度実行します。
ビットマップのビットが圧縮される画像圧縮/解凍でそれらをよく使用しました。http://en.wikipedia.org/wiki/Huffman_codingを使用すると、圧縮されるものはさまざまな数のビットで構成されます(すべてがバイト整列されているわけではありません)。したがって、エンコードまたはデコードするときにビットシフトする必要があります。 。
はい、あります。ご想像のとおり、デバイスのドライバの開発など、低レベルのプログラミングで見つかる可能性が最も高いです。しかし、私は医療機器からデータを受信するWebサービスを開発する必要があるC#プロジェクトに取り組みました。デバイスに保存されたすべてのバイナリデータはSOAPパケットにエンコードされましたが、バイナリデータは圧縮されてエンコードされました。したがって、それを解凍するには、たくさんのビット操作を行う必要があります。さらに、有用な情報を解析するには、多くのビットシフトを行う必要があります。たとえば、デバイスのシリアル番号は2番目のバイトの下半分などです。また、.NET(C#)の世界で、ビットマスキングとフラグ属性を使用している人もいますが、個人的にはそうする衝動はありませんでした。
数値をリトルエンディアンからビッグエンディアン形式に、またはその逆に変換する場合
ビットシフトは、オンラインゲームのプロトコルを解読する際によく使用されます。プロトコルは可能な限り小さな帯域幅を使用するように設計されているため、サーバー上のプレーヤーの数や名前などを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#)と見なすかはあなた次第です。
高速フーリエ変換— FFTとそのCooley-Tukey手法では、ビットシフト演算を使用する必要があります。
モニターのEDIDデータを読み取らなければならない組み込みシステムのプロジェクトで使用しています。EDIDの一部のデータは、次のようにエンコードされます。
バイト#3:
水平ブランキング-下位8ビット
バイト#4:
下位ニブル:水平ブランキング-上位4ビット
上位ニブル:その他
はい、ビットシフトは常に低レベルの組み込みソフトウェアで使用されています。また、非常に高速な数学演算を実行するためのほとんど手品として使用することもできます。
http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/