私は 8 桁の BCD 番号を持っており、それが有効な BCD 番号であるかどうかを確認する必要があります。プログラム (C/C++) でこれを作成するにはどうすればよいですか?
例: 0x12345678 は有効ですが、0x00f00abc は無効です。
前もって感謝します!
各 4 ビット量をチェックして、10 未満であることを確認する必要があります。効率のために、一度にできるだけ多くのビットを処理する必要があります。
ここでは、数字を分割して各数字の間に 0 を残し、それぞれに 6 を追加してオーバーフローをチェックします。
uint32_t highs = (value & 0xf0f0f0f0) >> 4;
uint32_t lows = value & 0x0f0f0f0f;
bool invalid = (((highs + 0x06060606) | (lows + 0x06060606)) & 0xf0f0f0f0) != 0;
編集:実際には、もう少しうまくいくことができます。オーバーフローを検出するのに 4 ビットは必要ありません。1 だけです。すべての桁を 2 で割ると、ビットが解放され、すべての桁を一度にチェックできます。
uint32_t halfdigits = (value >> 1) & 0x77777777;
bool invalid = ((halfdigits + 0x33333333) & 0x88888888) != 0;
@Mark Ransomに触発されました
bool invalid = (0x88888888 & (((value & 0xEEEEEEEE) >> 1) + (0x66666666 >> 1))) != 0;
// or
bool valid = !((((value & 0xEEEEEEEEu) >> 1) + 0x33333333) & 0x88888888);
各 BCD 桁の 1 の場所をマスクし、右にシフトしてから 6 を追加し、BCD 桁のオーバーフローをチェックします。
仕組み:各桁に +6 を追加することで、4 桁の合計の
オーバーフローを探します。*
abcd
+ 110
-----
*efgd
ただし、 のビット値はd
合計に寄与しないため、最初にそのビットをマスクして右にシフトします。これで、オーバーフロー ビットが8's
配置されました。これはすべて並行して行われ、これらのキャリー ビットをマスクして、0x88888888
設定されているかどうかをテストします。
0abc
+ 11
-----
*efg