ETH官方钱包

前往
大廳
主題

PackBCD格式

Yang | 2022-10-14 21:07:57 | 巴幣 1000 | 人氣 242

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

此格式常見於金融財務會計領域,譬如櫃買中心的上櫃股票IP行情網(wǎng)路規(guī)格書:

因為不是一般程式語言內(nèi)建的數(shù)字格式,所以直接ToString可能出現(xiàn)亂碼,如下圖

public class PackBCDConverter
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="high">高四位,數(shù)字0~9</param>
    /// <param name="low">低四位,數(shù)字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">高四位,數(shù)字0~9</param>
    /// <param name="low">低四位,數(shù)字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">數(shù)字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,數(shù)值為負值或帶有小數(shù)點時,會有另外的欄位,紀錄正負號和小數(shù)點位數(shù)
送禮物贊助創(chuàng)作者 !
0
留言

創(chuàng)作回應

更多創(chuàng)作