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ù)