乗算や除算を使わずにBCD変換するプログラムを考えてみた。
引数の数値範囲に限定してあらかじめ計算しておいた結果をテーブル参照することで実行時には加算のみですむようになっている。全ての数値を単純に参照変換するよりもメモリ量は圧倒的に少なくてすむ。
10の剰余を求めたいときは(計算結果 & 0x0F)するだけで良い。
さて、このプログラムは乗算や除算を使っていないと言えるだろうか?
参考にした計算式: n + 6 * (n / 10);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
unsigned short bin2bcd(unsigned char n) { static constexpr unsigned char DIV10MUL6[] = { 0, 0, 0, 0, 0, // 0- 9 6, 6, 6, 6, 6, // 10- 19 12, 12, 12, 12, 12, // 20- 29 18, 18, 18, 18, 18, // 30- 39 24, 24, 24, 24, 24, // 40- 49 30, 30, 30, 30, 30, // 50- 59 36, 36, 36, 36, 36, // 60- 69 42, 42, 42, 42, 42, // 70- 79 48, 48, 48, 48, 48, // 80- 89 54, 54, 54, 54, 54, // 90- 99 60, 60, 60, 60, 60, // 100-109 66, 66, 66, 66, 66, // 110-119 72, 72, 72, 72, 72, // 120-129 78, 78, 78, 78, 78, // 130-139 84, 84, 84, 84, 84, // 140-149 90, 90, 90, 90, 90, // 150-159 96, 96, 96, 96, 96, // 160-169 102, 102, 102, 102, 102, // 170-179 108, 108, 108, 108, 108, // 180-189 114, 114, 114, 114, 114, // 190-199 120, 120, 120, 120, 120, // 200-209 126, 126, 126, 126, 126, // 210-219 132, 132, 132, 132, 132, // 220-229 138, 138, 138, 138, 138, // 230-239 144, 144, 144, 144, 144, // 240-249 150, 150, 150 // 250-255 }; unsigned short bcd = n + DIV10MUL6[n >> 1]; if (bcd >= 0x0A0) /* >= 100 */ bcd += 0x60; if (bcd >= 0x1A0) /* >= 200 */ bcd += 0x60; return bcd; } |