30

私はC#でシフト演算子を研究していて、コードでそれらをいつ使用するかを見つけようとしていました。

答えは見つかりましたが、Javaの場合は次のことができます。

a)整数の乗算と除算の演算を高速化します。

* 4839534 * 4 *は次のように実行できます: 4839534 << 2

また

543894/2は次のように実行できます:543894 >> 1

ほとんどのプロセッサでは、乗算よりもはるかに高速に演算をシフトします。

b)バイトストリームをint値に再アセンブルする

c)赤、緑、青の色は別々のバイトでコード化されているため、グラフィックスを使用して操作を高速化するため。

d)小さな数を1つの長いものに詰める...


b、c、dについては、ここで実際のサンプルを想像することはできません。

これらすべての項目をC#で実行できるかどうか誰かが知っていますか?C#のシフト演算子のより実用的な使用法はありますか?

4

4 に答える 4

38

コンパイラがこれを自動的に処理するため、最適化の目的でこれらを使用する必要はありません。

ビットをシフトすることがコードの本当の目的である場合にのみ使用してください(質問の残りの例のように)。残りの時間は、乗算と除算を使用するだけなので、コードの読者は一目でそれを理解できます。

于 2009-12-19T17:44:47.943 に答える
17

非常に説得力のある理由がない限り、私の意見では、そのような巧妙なトリックを使用すると、通常、付加価値がほとんどない、より混乱したコードが作成されます。コンパイラーの作成者は賢い開発者であり、平均的なプログラマーよりも多くのトリックを知っています。たとえば、整数を2の累乗で除算する方が、シフト演算子を使用すると除算よりも高速ですが、コンパイラが自動的に実行するため、おそらく必要ありません。これは、Microsoft C /C++コンパイラとgccの両方がこれらの最適化を実行するアセンブリを見るとわかります。

于 2009-12-19T17:49:59.217 に答える
15

過去に出くわした面白い使い方を紹介します。この例は、「 [Flags] Enum AttributeはC#で何を意味するのですか?」という質問に対する補足回答から恥知らずにコピーされています。

[Flags]
public enum MyEnum
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3
}

1, 2, 4, 8, ...これは、特に17個のフラグを超えた場合に、リテラル値を書き込むよりも簡単に拡張できます。

トレードオフは、31を超えるフラグ(1 << 30)が必要な場合は、列挙型を符号付き整数よりも高い上限を持つものとして指定するように注意する必要があります(public enum MyEnum : ulongたとえば、として宣言することにより、 64フラグ)。それの訳は...

1 << 29 == 536870912
1 << 30 == 1073741824
1 << 31 == -2147483648
1 << 32 == 1
1 << 33 == 2

対照的に、列挙値を直接2147483648に設定すると、コンパイラはエラーをスローします。

ClickRickが指摘しているように、列挙型がulongから派生している場合でも、ビットシフト操作はulongに対して実行する必要があります。そうしないと、列挙型の値が壊れます。

[Flags]
public enum MyEnum : ulong
{
    None   = 0,
    First  = 1 << 0,
    Second = 1 << 1,
    Third  = 1 << 2,
    Fourth = 1 << 3,

    // Compiler error:
    // Constant value '-2147483648' cannot be converted to a 'ulong'
    // (Note this wouldn't be thrown if MyEnum derived from long)
    ThirtySecond = 1 << 31,

    // so what you would have to do instead is...
    ThirtySecond = 1UL << 31,
    ThirtyThird  = 1UL << 32,
    ThirtyFourth = 1UL << 33
}
于 2014-06-03T20:49:08.303 に答える
6

2進数システム算術シフトに関するこれらのウィキペディアの記事をチェックしてください。彼らはあなたの質問に答えると思います。

今日のビジネスアプリケーションでは、シフト演算子に遭遇することはめったにありません。これらは、ハードウェアと相互作用したり、パックされたデータを操作したりする低レベルのコードに頻繁に表示されます。それらは64kメモリセグメントの時代にもっと一般的でした。

于 2009-12-19T17:43:48.763 に答える