-
[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(); }
코드 실행 결과
반응형'개발' 카테고리의 다른 글
[MFC] CreateProcess() 핸들 누수 수정 : C6335 leaking process information handle (0) 2022.08.12 MFC CloseHandle 0xC0000008: An invalid handle was specified (0) 2022.08.11 윈도우10 로지텍 페블 블루투스 마우스 끊김 현상 해결 - 마우스 설정 변경 (0) 2021.07.27 윈도우10 블루투스 마우스 끊김 현상 해결 - 전원관리 (0) 2021.01.12 포토샵 CS3 메뉴 크기 고해상도 화면에서 변경하기 (0) 2021.01.08