2

私は 8 桁の BCD 番号を持っており、それが有効な BCD 番号であるかどうかを確認する必要があります。プログラム (C/C++) でこれを作成するにはどうすればよいですか?

例: 0x12345678 は有効ですが、0x00f00abc は無効です。

前もって感謝します!

4

4 に答える 4

10

各 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;
于 2015-03-20T21:27:33.830 に答える
2

@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
于 2015-03-20T21:44:34.613 に答える