0
0

More than 1 year has passed since last update.

Densely Packed Decimal (DPD) を整理する

Last updated at Posted at 2020-02-06

10進数3桁の10ビット符号化 は見づらかったので、ビット並びを整理した表にする。

符号 百位 十位 一位 百位 十位 一位
$0$ $h_2h_1h_0$ $m_2m_1m_0$ $l_2l_1l_0$ $0〜7$ $0〜7$ $0〜7$
$100$ $h_2h_1h_0$ $m_2m_1m_0$ $l_0$ $0〜7$ $0〜7$ $8〜9$
$101$ $h_2h_1h_0$ $m_0$ $l_2l_1l_0$ $0〜7$ $8〜9$ $0〜7$
$110$ $h_0$ $m_2m_1m_0$ $l_2l_1l_0$ $8〜9$ $0〜7$ $0〜7$
$111\ 00$ $h_0$ $m_0$ $l_2l_1l_0$ $8〜9$ $8〜9$ $0〜7$
$111\ 01$ $h_0$ $m_2m_1m_0$ $l_0$ $8〜9$ $0〜7$ $8〜9$
$111\ 10$ $h_2h_1h_0$ $m_0$ $l_0$ $0〜7$ $8〜9$ $8〜9$
$111\ 11\ xx$ $h_0$ $m_0$ $l_0$ $8〜9$ $8〜9$ $8〜9$
C言語用変換テーブルを生成する Python プログラム
Python
#!/usr/bin/env python3

def decode(e):
    (d1, d2, d3) = ((e >> 7) & 7, (e >> 4) & 7, (e >> 0) & 7)
    (m1, m2, m3) = (d1 & 6, d2 & 6, d3 & 6)
    (l1, l2, l3) = (d1 & 1, d2 & 1, d3 & 1)
    mode = (e >> 1) & 7
    if mode == 4:
        (d1, d2, d3) = (d1,   d2,   l3 | 8)
    elif mode == 5:
        (d1, d2, d3) = (d1,   l2 | 8, l3 | m2)
    elif mode == 6:
        (d1, d2, d3) = (l1 | 8, d2,   l3 | m1)
    elif mode == 7:
        mode = (e >> 5) & 3
        if mode == 0:
            (d1, d2, d3) = (l1 | 8, l2 | 8,  l3 | m1)
        elif mode == 1:
            (d1, d2, d3) = (l1 | 8, l2 | m1, l3 | 8)
        elif mode == 2:
            (d1, d2, d3) = (d1,   l2 | 8,  l3 | 8)
        elif mode == 3:
            (d1, d2, d3) = (l1 | 8, l2 | 8,  l3 | 8)
    return (d1*100 + d2*10 + d3)


def decode_table():
    return [decode(n) for n in range(1024)]


def encode(n):
    if n >= 1000:
        return 0xffff
    (d1, d2, d3) = (int(n/100) % 10, int(n/10) % 10, int(n/1) % 10)
    (h1, m1, l1) = (d1 & 8, d1 & 6, d1 & 1)
    (h2, m2, l2) = (d2 & 8, d2 & 6, d2 & 1)
    (h3, m3, l3) = (d3 & 8, d3 & 6, d3 & 1)
    (d1, d2, d3) = (d1 << 7, d2 << 4, d3)
    (l1, l2, l3) = (l1 << 7, l2 << 4, l3)
    mode = (h1 >> 1) | (h2 >> 2) | (h3 >> 3)
    if mode == 0:
        return (0x00 | d1 | d2 | d3)
    elif mode == 1:
        return (0x08 | d1 | d2 | l3)
    elif mode == 2:
        return (0x0a | d1 | l2 | l3 | (m3 << 4))
    elif mode == 4:
        return (0x0c | l1 | d2 | l3 | (m3 << 7))
    elif mode == 6:
        return (0x0e | l1 | l2 | l3 | (m3 << 7))
    elif mode == 5:
        return (0x2e | l1 | l2 | l3 | (m2 << 7))
    elif mode == 3:
        return (0x4e | d1 | l2 | l3)
    elif mode == 7:
        return (0x6e | l1 | l2 | l3)
    return -1


def encode_table():
    return [encode(n) for n in range(1024)]


def dump(l, m='', t=''):
    for n in range(len(l)):
        m = m + (' %#06x,' % l[n])
        if ((n+1) & 7) == 0:
            m = m + (' /* %#05x */\n' % ((n | 7) & ~7))
    return (m+t)


for n in range(1000):
    e = encode(n)
    d = decode(e)
    if n != d:
        print('%d != %d' % (n, d))
        raise Exception('Bug!')

print(dump(decode_table(), m='unsigned short decode_table[1024] = {\n', t='};'))
print(dump(encode_table(), m='unsigned short encode_table[1024] = {\n', t='};'))
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0