1

unsigned int A(32ビット)と別のunsigned int Bが与えられ、Bのバイナリ形式はAの10個の「最も信頼性の低い」ビットを示します。Aの1024個の潜在的な値すべてを拡張する最も速い方法は何ですか。私はCでこれを行うことを探しています。

たとえば、uint Bは、バイナリ形式(最も信頼性の低い10ビット)で常に101と220を持つことが保証されています。

たとえば、

A = 2323409845  
B = 1145324694

それらのバイナリ表現は次のとおりです。

a=10001010011111000110101110110101

b=01000100010001000100010010010110

BはAの最も信頼性の低い10ビットを示します。したがって、Bで1に設定されている各ビットは、Aの信頼性の低いビットを示します。

Aの10ビットのいずれかを切り替えて作成された1024個の可能な値すべてを計算したいと思います。

4

3 に答える 3

2

これが確実に「最速」であるという保証はありませんが、これは私が行うことです。まず、固定ビットをふるいにかけます。

uint32_t const reliable_mask = ~B;
uint32_t const reliable_value = A & reliable_mask;

次に、信頼できないビットの1024個の可能な値の配列を前処理します。

uint32_t const unreliables[1024] = /* ... */

そして最後に、私はそれらすべてを一緒にまたはすべて一緒にします:

for (size_t i = 0; i != 1024; ++i)
{
   uint32_t const val = reliable_value | unreliables[i];
}

信頼性の低いビットを取得するには、ループオーバーして[0, 1024)(おそらく既存のループ内でも)、ビットを必要な位置に「拡散」することができます。

于 2011-11-29T01:41:19.133 に答える
1

これは基本的にKerrekが使用する手法に従いますが、難しい部分を肉付けします。

int* getValues(int value, int unreliable_bits)
{
  int unreliables[10];
  int *values = malloc(1024 * sizeof(int));
  int i = 0;
  int mask;

関数定義といくつかの変数宣言。ここに、valueはあなたAであり、unreliable_bitsはあなたBです。

  value &= ~unreliable_bits;

信頼できないビットをマスクして、信頼できないビットを含む整数をOR演算すると、value必要なものが得られるようにします。

  for(mask = 1;i < 10;mask <<= 1)
  {
    if(mask & unreliable_bits)
      unreliables[i++] = mask;
  }

ここでは、後で使用するために、信頼できない各ビットを個々のintに取り込みます。

  for(i = 0;i < 1024;i++)
  {
    int some_unreliables = 0;
    int j;
    for(j = 0;j < 10;j++)
    {   
      if(i & (1 << j)) 
        some_unreliables |= unreliables[j];
    }   
    values[i] = value | some_unreliables;
  }

機能の肉。外側のループは、必要な各出力の上にあります。次に、ループ変数の下位10ビットを使用して、整数が下位10ビットのすべての可能性を通過するiという事実を使用して、信頼できない各ビットをオンにするかどうかを決定します。01023

  return values;
}

最後に、作成した配列を返します。これは、質問の値Aと与えられた値でテストするために使用できる短いメインです。B

int main()
{
  int *values = getValues(0x8A7C6BB5, 0x44444496);
  int i;
  for(i = 0;i < 1024;i++)
    printf("%X\n", values[i]);
}
于 2011-11-29T05:18:13.957 に答える
1

b次のように、ビットの1024の異なる設定を繰り返すことができます。

unsigned long b = 1145324694;
unsigned long c;

c = 0;
do {
    printf("%#.8lx\n", c & b);
    c = (c | ~b) + 1;
} while (c);

これらを使用して変更するaには、XORを使用できます。

unsigned long a = 2323409845;
unsigned long b = 1145324694;
unsigned long c;

c = 0;
do {
    printf("%#.8lx\n", a ^ (c & b));
    c = (c | ~b) + 1;
} while (c);

この方法には、テーブルを事前に計算する必要がなく、1024をハードコーディングする必要がないという利点があります。これは、の1ビット数に完全に基づいてループしbます。

整数ベクトル命令を使用してこのアルゴリズムを並列化することも比較的簡単なことです。

于 2011-11-29T07:27:48.827 に答える