2

非常に単純な目的を持つコードをインターネット上で見つけましたが、それは醜いアプローチを使用しています。おそらく、作成者はスイッチケースを使用して、以前に定義された Enum のいくつかの (連続していない) 値がそのスコープに属しているかどうかを判断しています。そうであれば、関数は戻りtrue、それだけです。それ以外の場合は、 を返しますfalse

実際には次のようになります。

switch(value) {
case ONE:
case TWO:
/* many similar lines later */
case TWENTY:
case TWENTY_FIVE:
/* an afternoon later */
case ONE_HUNDRED:
    return true;
default:
    return false;
}

switch ケースの使用は、コンパイラによって生成されたジャンプ テーブルのおかげで瞬時にルックアップできることで正当化されます (ただし、ジャンプ テーブルは、私が収集したものからの瞬時のルックアップを必ずしも意味するわけではありません)。それでも、無数の不要なコード行が生成されます。

関数のインライン化と関数ポインターの配列の使用について読んだことがありますが、そのような特定のケースでそれを使用する方法がわかりません。

このような単純なケース (しゃれは意図されていません) で行も書かないようにするにはどうすればよいですか?case X:

4

3 に答える 3

8

バインドされた整数に基づいてブール値を効率的に計算することは、ビット操作の仕事です。

const unsigned long long ps[2] = {0x28208a20a08a28ac, 0x800228a202088288};

bool is_prime(unsigned x)
{
    return (x < 128) && ((ps[x >> 6] >> (x & 63)) & 1);
}

配列に格納されている数値のバイナリ表現を見ると、1 ビットは素数を表し、0 ビットは合成数を表します。

   2    8    2    0    8    a    2    0    a    0    8    a    2    8    a    c
0010 1000 0010 0000 1000 1010 0010 0000 1010 0000 1000 1010 0010 1000 1010 1100
    59             47     41           31        23     17      11      5   2
 61        53           43     37        29           19     13       7    3

これを 128 を超える数値にスケーリングするには、単純に配列のサイズを増やして、<比較にパッチを適用しis_primeます。定数 6 と 63 は、 のビット数に由来しunsigned long longます。

于 2016-02-29T19:34:29.420 に答える
0

値をスキップする奇数の列挙型があるため、ソリューションを反転できます。ただし、スキップされた番号を宣言する必要があります (スキップするのが数個だけの場合)。

if( value > ONE_HUNDRED || value < ONE )
{
    return false;
}
else
{
    switch(value)
    {
         case SKIPPED_FIRST:
         case SKIPPED_SECOND:
         {
             return false;
         }
         break;
         default:
         {
             return true;
         }
    }
}
于 2016-02-29T18:40:37.657 に答える