各ビットを 8 回繰り返してanunsigned char
を anに膨らませたいと思います。uint64_t
例えば
char -> uint64_t
0x00 -> 0x00
0x01 -> 0xFF
0x02 -> 0xFF00
0x03 -> 0xFFFF
0xAA -> 0xFF00FF00FF00FF00
現在、ビットが設定されているかどうかをテストするためにビットシフトを使用して、これを達成するために次の実装を行っています。
#include <stdint.h>
#include <inttypes.h>
#define BIT_SET(var, pos) ((var) & (1 << (pos)))
static uint64_t inflate(unsigned char a)
{
uint64_t MASK = 0xFF;
uint64_t result = 0;
for (int i = 0; i < 8; i++) {
if (BIT_SET(a, i))
result |= (MASK << (8 * i));
}
return result;
}
しかし、私は C にかなり慣れていないので、このように個々のビットをいじることで、これを行うためのより良い (つまり、より効率的な) 方法があるのではないかと少し考えが変わります。
編集
して追加
OK、テーブル ルックアップ ソリューションを試した後の結果を次に示します。ただし、ルーチンを直接テストしたのではなく、より大きな関数 (正確にはバイナリ行列の乗算) の一部としてテストしたため、結果がどうなるかに影響した可能性があることに注意してください。したがって、私のコンピューターで、100 万の 8x8 行列を乗算し、次のようにコンパイルすると:
gcc -O2 -Wall -std=c99 foo.c
私は得た
./a.out original
real 0m0.127s
user 0m0.124s
sys 0m0.000s
./a.out table_lookup
real 0m0.012s
user 0m0.012s
sys 0m0.000s
したがって、少なくとも私のマシン (言及すべき仮想マシン 64 ビット Linux Mint) では、テーブル ルックアップ アプローチは約 10 倍のスピードアップを提供するように見えるので、それを答えとして受け入れます。