コンパイル時にパリティを生成したいとします。パリティ計算にはリテラル定数が与えられ、適切なオプティマイザーを使用すると、それ自体が単一の定数に要約されます。次に、 Cプリプロセッサを使用した次のパリティ計算を見てください。
#define PARITY16(u16) (PARITY8((u16)&0xff) ^ PARITY8((u16)>>8))
#define PARITY8(u8) (PARITY4((u8)&0x0f) ^ PARITY4((u8)>>4))
#define PARITY4(u4) (PARITY2((u4)&0x03) ^ PARITY2((u4)>>2))
#define PARITY2(u2) (PARITY1((u2)&0x01) ^ PARITY1((u2)>>1))
#define PARITY1(u1) (u1)
int message[] = { 0x1234, 0x5678, PARITY16(0x1234^0x5678));
これにより、コンパイル時にパリティが計算されますが、大量の中間コードが生成され、式の16個のインスタンスに拡張されます。これは、u16
たとえば任意の複雑な式にすることができます。問題は、Cプリプロセッサが中間式を評価できず、一般的な場合はテキストのみを展開することです(整数演算をその場で実行するように強制できますが、些細な場合、またはギガバイトの#definesを使用する場合のみ)。3ビットのパリティは、算術式によって一度に生成できることがわかりました([0..7]*3+1)/4
。これにより、16ビットのパリティが次のマクロに削減されます。
#define PARITY16(u16) ((4 & ((((u16)&7)*3+1) ^ \
((((u16)>>3)&7)*3+1) ^ \
((((u16)>>6)&7)*3+1) ^ \
((((u16)>>9)&7)*3+1) ^ \
((((u16)>>12)&7)*3+1) ^ \
((((u16)>>15)&1)*3+1))) >> 2))
u16
これは6倍しか拡大しません。(拡張の数に関して)さらに安価な方法はありますか?たとえば、4,5などの直接式はありますか?ビットパリティ?(x*k+d)/m
3ビットを超える範囲の許容可能な(オーバーフローしない)値k、d、mの形式の線形式の解を見つけることができませんでした。プリプロセッサのパリティ計算のためのより賢いショートカットを持っている人はいますか?