これは簡単。前回bit_pattern()で取得したビットパターンのマッチングをすればいいだけ。列挙したビットパターンに対応する数字を加えて、Cのコードに入れるだけ。ハードコーディング万歳。列挙したビットパターンを対応する数字に変換するには、デバッグも含めてhex->binの変換を実行してチェックすることにします。
use strict; while(<>){ print "pattern: $_"; s/.*\{//; s/, \}.*//; s/0x//g; my @l = map { my $str = unpack("B32", pack("H*", $_)); $str =~ s/0/ /g; $str =~ s/1/\*/g; $str; } split(/, /); print join("\n", @l), "\n"; }
"unpack("B32", pack("H*", $_));"はhex -> 32bit binaryに変換する一番簡単な方法。いちいちビットシフトなんてLLでやることじゃないよね。他のLLにこういうAPIがあるのかは知らないけど・・・。
肝心のパターンマッチ処理はこんな感じ。フラグを使わない手抜きマッチング。bit_patternsの最後には、対応するカウントが入ってます。この配列はint型なので、整数になるように10倍した値を入れてます。1ビットシフト*1とかにしたほうがCPUにはやさしいのかも・・・?
#define BIT_PATTERNS_NUM 10 void get_count_max(graph_area *g) { int bit_patterns[BIT_PATTERNS_NUM][COUNTER_HEIGHT+1] = { {0x00000080, 0x00000180, 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x000001c0, 10}, {0x000403c0, 0x000c0200, 0x00040380, 0x00040040, 0x00040040, 0x00043240, 0x000e3180, 15}, {0x000c0780, 0x00120400, 0x00020700, 0x00040080, 0x00080080, 0x00106480, 0x001e6300, 25}, {0x000f0000, 0x00080000, 0x000e0000, 0x00010000, 0x00010000, 0x00090000, 0x00060000, 50}, {0x00086000, 0x00189000, 0x0008b000, 0x0008d000, 0x00089000, 0x00089000, 0x001c6000, 100}, {0x000cf000, 0x00128000, 0x0002e000, 0x00041000, 0x00081000, 0x00109000, 0x001e6000, 250}, {0x000f3000, 0x00084800, 0x000e5800, 0x00016800, 0x00014800, 0x00094800, 0x00063000, 500}, {0x000cf300, 0x00128480, 0x0002e580, 0x00041680, 0x00081480, 0x00109480, 0x001e6300, 2500}, {0x00086300, 0x00189480, 0x0008b580, 0x0008d680, 0x00089480, 0x00089480, 0x001c6300, 1000}, {0x000f3180, 0x00084a40, 0x000e5ac0, 0x00016b40, 0x00014a40, 0x00094a40, 0x00063180, 5000}, }; int i, j; g->count_max = -1.0; /* default value */ for(i=0; i<BIT_PATTERNS_NUM; i++){ for(j=0; j<COUNTER_HEIGHT; j++){ if(g->bit_pattern[j] != bit_patterns[i][j]) break; } if(j == COUNTER_HEIGHT){ g->count_max = (double)bit_patterns[i][COUNTER_HEIGHT]/10.0; break; } } printf("count_max: %.1f\n", g->count_max); if(g->count_max == -1.0){ fprintf(stderr, "error: not mathced count.\n"); destruct_graph(g); exit(EXIT_FAILURE); } }
*1:小数は0.5しかないので