ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C#] BCD타입이란? 문자열 BCD 변환하기 코드 예제
    개발 2022. 3. 31. 13:57
    반응형

     

    프로젝트 진행 중에 현재 날짜를 메모리에 써줘야 하는 경우가 있었는데

    사양 문서에 BCD 타입으로 저장하라고 되어 있었다

    BCD 형식은 뭐지? 그래서 찾아봤다

     

    BCD (binary-coded decimal) 이진화 십진 표기법

    BCD는 이진수 4bit로 십진수 한 자리를 표현하는 기수법이다

    또한 8421 코드라고도 하는데 각 비트의 자리값 즉, 이진수 4개 비트의 가중치 (8-4-2-1)로 표현하기 때문이다

    예를 들어 십진수 1436은

    1436 - 0001 0100 0011 0110과 같다


    BCD값 0110를 십진수로 변환하면 1이 있는 비트의 가중치를 더해주면 된다

    (BCD) 0110 = (0*8) + (1*4) + (1*2) + (0*1) = 6 


    십진수 한 자리를 변환하기 때문에 0 ~ 9에 해당하는 이진수만 알고 있으면 된다


    BCD가 이진수 표현에 비해 갖는 장점 중 하는, 표현할 수 있는 숫자 크기에 제한이 없다는 것이다.
    추가되는 자릿수만큼 새로운 4bit를 추가하면 된다

     

    - BCD 변환 예제 코드

    현재 날짜를 얻어와서 BCD 타입으로 변환하여 출력하고, 다시 BCD 타입을 string으로 변환하여 출력하는 예제이다

    BCD 변환 로직은 여러 가지 방법으로 할 수 있겠으나 예제에서는 두 가지 방식으로 작업했다

    1. Char.GetNumericValue 메서드를 이용하여 string을 index 순서대로 읽으며 비트 연산을 하는 방법

    2. string 을 loop 돌면서 byte 타입으로 변환하는 방법

    그리고 BCD를 다시 string으로 변환할 때는 비트 연산과 0x0F 마스킹을 이용하였다

     

    아래와 같은 코드로 BCD 변환 작업을 할 수 있다

            public Form1()
            {
                InitializeComponent();
                DisplayBCD();
            }
    
            private void DisplayBCD()
            {
                string dateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
                Console.WriteLine("DateTime.Now : {0}", dateTime);
    
                Console.WriteLine("------ UseGetNumericValue");
                foreach (int v in UseGetNumericValue(dateTime))
                {
                    ConsoleWriteline(v);
                }
    
                Console.WriteLine("------ StringToBCD");
    
                byte[] bcdByte = StringToBCD(dateTime);
                foreach (int v in StringToBCD(dateTime))
                {
                    ConsoleWriteline(v);
                }
    
                Console.WriteLine("------ BCDToString");
                Console.WriteLine(BCDToString(bcdByte));
            }
            private void ConsoleWriteline(int value)
            {
                Console.WriteLine("{0}", Convert.ToString(value, 16).PadLeft(4, '0'));
    
                string binaryStr = Convert.ToString(value, 2);
                int zeroCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(binaryStr.Length) / 8)) * 8;
                Console.WriteLine(Regex.Replace(binaryStr.PadLeft(zeroCount, '0'), ".{4}", "$0 ", RegexOptions.RightToLeft));
            }
    
            private int[] UseGetNumericValue(string value)
            {
                int[] bcd = new int[4];
    
                bcd[0] = ((int)Char.GetNumericValue(value, 0)) << 12 | ((int)Char.GetNumericValue(value, 1)) << 8 | 
                    ((int)Char.GetNumericValue(value, 2)) << 4 | ((int)Char.GetNumericValue(value, 3));
                bcd[1] = ((int)Char.GetNumericValue(value, 4)) << 12 | ((int)Char.GetNumericValue(value, 5)) << 8 | 
                    ((int)Char.GetNumericValue(value, 6)) << 4 | ((int)Char.GetNumericValue(value, 7));
                bcd[2] = ((int)Char.GetNumericValue(value, 8)) << 12 | ((int)Char.GetNumericValue(value, 9)) << 8 | 
                    ((int)Char.GetNumericValue(value, 10)) << 4 | ((int)Char.GetNumericValue(value, 11));
                bcd[3] = ((int)Char.GetNumericValue(value, 12)) << 4 | ((int)Char.GetNumericValue(value, 13));
    
                return bcd;
            }
    
            private byte[] StringToBCD(string value)
            {
                int valueLength = value.Length;
                byte[] bcd = new byte[valueLength / 2];
    
                for (int i = 0; i < valueLength; i += 2)
                {
                    bcd[i / 2] = Convert.ToByte(value[i].ToString(), 16);
                    bcd[i / 2] <<= 4;
                    bcd[i / 2] |= Convert.ToByte(value[i + 1].ToString(), 16);
                }
    
                return bcd;
            }
    
            private string BCDToString(byte[] bcd)
            {
                StringBuilder sb = new StringBuilder();
    
                for (int i = 0; i < bcd.Length; i++)
                {
                    sb.Append(bcd[i] >> 4);
                    sb.Append(bcd[i] & 0x0F);
                }
    
                return sb.ToString();
            }

     

    코드 실행 결과

     

    반응형

    댓글

Designed by Tistory.