PackBCD格式是一種數值儲存格式,用4個bits紀錄數字0~9,1個byte拆成高四位和低四位,可以儲存00~99

此格式常見於金融財務會計領域,譬如櫃買中心的上櫃股票IP行情網路規格書:
https://dsp.tpex.org.tw/web/system/trainsmit.php

因為不是一般程式語言內建的數字格式,所以直接ToString可能出現亂碼,如下圖

packbcd1.jpg

public class PackBCDConverter
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="high">高四位,數字0~9</param>
    /// <param name="low">低四位,數字0~9</param>
    /// <returns></returns>
    public static char ToPackBCD(in byte high, in byte low)
    {
        return (char)((high << 4) | low);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="high">高四位,數字0~9</param>
    /// <param name="low">低四位,數字0~9</param>
    /// <returns></returns>
    public static char ToPackBCD(in char high, in char low)
    {
        return ToPackBCD((byte)(high - '0'), (byte)(low - '0'));
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source">數字00~99</param>
    /// <returns></returns>
    public static char ToPackBCD(in byte source)
    {
        return ToPackBCD((byte)(source / 10), (byte)(source % 10));
    }

    public static char[] ToPackBCD(in string source)
    {
        List<char> result = new List<char>();

        if (string.IsNullOrEmpty(source))
        {
            return result.ToArray();
        }

        bool isOdd = source.Length % 2 == 1;

        if (isOdd)
        {
            result.Add(ToPackBCD('0', source[0]));

            if (source.Length == 1)
            {
                return result.ToArray();
            }
        }

        for (int i = isOdd ? 1 : 0; i < source.Length; i += 2)
        {
            result.Add(ToPackBCD(source[i], source[i + 1]));
        }

        return result.ToArray();
    }

    public static int ToInt(in char source)
    {
        return (source >> 4) * 10 + (source & 0x0F);
    }

    public static int ToInt(in char[] source, in int count = sizeof(int))
    {
        if (source == null || source.Length <= 0 || count <= 0 || count > sizeof(int))
        {
            return -1;
        }

        int cnt = source.Length > count ? count : source.Length;

        int result = ToInt(source[0]);

        for (int i = 1; i < cnt; ++i)
        {
            result = result * 100 + ToInt(source[i]);
        }

        return result;
    }

    public static long ToLong(in char[] source, in int count = sizeof(long))
    {
        if (source == null || source.Length <= 0 || count <= 0 || count > sizeof(long))
        {
            return -1;
        }

        int cnt = source.Length > count ? count : source.Length;

        long result = ToInt(source[0]);

        for (int i = 1; i < cnt; ++i)
        {
            result = result * 100 + ToInt(source[i]);
        }

        return result;
    }
}

單元測試:
PackBCDConverter.ToPackBCD("01234567890").Length
6
PackBCDConverter.ToLong(PackBCDConverter.ToPackBCD("01234567890"))
1234567890
PackBCDConverter.ToPackBCD("1234567890").Length
5
PackBCDConverter.ToLong(PackBCDConverter.ToPackBCD("1234567890"))
1234567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("1234567890"))
12345678
PackBCDConverter.ToLong(PackBCDConverter.ToPackBCD("234567890"))
234567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("234567890"))
2345678
PackBCDConverter.ToLong(PackBCDConverter.ToPackBCD("34567890"))
34567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("34567890"))
34567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("4567890"))
4567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("567890"))
567890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("67890"))
67890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("7890"))
7890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("890"))
890
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("90"))
90
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD("0"))
0
PackBCDConverter.ToInt(PackBCDConverter.ToPackBCD(""))
-1

單元測試正常

另外補充,實務上PackBCD只用來儲存0~9,數值為負值或帶有小數點時,會有另外的欄位,紀錄正負號和小數點位數

arrow
arrow
    文章標籤
    程式設計 C# UnitTest
    全站熱搜
    創作者介紹
    創作者 Yang 的頭像
    Yang

    GNAySolution

    Yang 發表在 痞客邦 留言(0) 人氣()