C\\C++
[C/C++] 10, 2, 16, 8 진수 변환 규칙
아몬드통
2023. 1. 7. 22:16
난 이걸 왜 또 하고 있을까...
- 컴퓨터와 가까운 Low Level 언어를 배울 수록 이런 진법 변환과 연관성이 많아진다.
- 나야 배운지가 오래되었으니.. 대강은 알고 있지만 이참에 확실히 정리를 해두자.
- 변환을 직접 계속 하다보면 결국 변환 방법의 반복적인 규칙을 알게 된다. 이걸 이해하는 게 전부다
먼저 공식? 변환 규칙? 을 알아보자.
- 우리는 사람이고, 사람에게 제일 익숙한 수는 10진수이다. 0,1,2,3,4,5,6,7,8,9 의 기호?문자? 를 가지고 수를 표현하는 것이다.
- 기호, 문자라고 했는데 0,1,2,3 이런 숫자가 아니라 §1, §2 이런 식으로 수를 표기하기로 약속 했다면 우린 다르게 생긴 숫자를 사용하고 있을 것이다. 그래서 그냥 0,1,2,3 도 하나의 문자라고 생각하는 게 좋다.
- 그래서 위의 내용대로 다른 진법들을 설명하면 2진수는 0과1이라는 기호?문자?로 수를 표현하는 것이 전부다. 8진수는 0,1,2,3,4,5,6,7 로 수를 표현, 16진수는 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f 로 수를 표현한다.
- 어찌보면 위의 설명한 내용이 전부다. 다시 본론으로 가서 변환 설명을 해보자.
10진수 -> 2진수
- 더 간단한 방법은 소인수분해를 2로만해서 나머지와 몫을 더해주면 되고 그게 더 현명한 방법이긴 하다.
- 다만 내 개인적인 이해를 위해서 0부터 어떻게 10진수가 2진수로 만들어 지는 지 설명해보자.
- 0과 1, 2개로 표기하고 2이상이 되면 왼쪽에 1을 더해주고 원래 자리를 0으로 만든다.
10진수 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
2진수 | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 |
- 0,1,2,3 까지는 위에 설명 그대로다. 1씩 증가하고 2가 넘으면 왼쪽에 1을 더해주고 원래 자리를 0으로 만든다.
- 3에서 +1을 해서 4가 될때 약간의 추가 설명이 필요할 것 같다.
- 10진수 3의 2진수인 11에 +1을 하면 12, 2가 나왔으니 왼쪽에 1을 더해주고 원래 자리를 0으로 만들면 20. 다시 2가 나왔다! 그러면 동일하게 해야하지 않을까?
- 그러면 10진수 20에 동일한 연산을 해보자. 왼쪽에 1을 더하면 120이고 2가 원래자리였으니 0으로 만들면 100이다.
- 더 이상 2가 넘는 숫자가 없으니 2진수 100이 10진수로 4이다. (아래는 원래 설명이니 패스하자)
2가 넘었으니 위의 설명대로 바꿔보자. 12 에서 2부분의 왼쪽으로 1을 더해주면 22, 그리고 원래자리를 0으로 만들면 20이 된다.2진수 20이 나왔다. 다시 설명을 보자. 2가 넘으면 왼쪽에 1을 더해주고 원래 자리를 0으로 만든다고 했었다.그렇다면 20이라는 것도 동일하게 처리해야하지 않을까? 그러면 20을 동일하게 계산해보자.2의 왼쪽에 1을 추가한다. 그러면 120이 나온다. 그리고 2를 0으로 만든다. 그러면 100이고 이 값은 2진수로 4이다.- 드디어 원하는 숫자가 나왔다! 위의 설명에 약간의 추가를 하면 될것 같다.
- "모든 자리에서" 0과 1, 2개로 표기하고 2가 넘으면 왼쪽에 1을 더해주고 원래 자리를 0으로 만든다.
- 이건 0부터 차례대로 설명하기 위한 내용이고, 더 쉽게 2로 나누어서 각 자리의 나머지를 더하는 방법이 있다.
당연히 이것보다 훨씬 간단하고 좋은 계산법도 많고 설명도 많지만, 어차피 내가 이해하는 게 중요하니까 내가 이해하고 있는대로 설명해봤다....
10진수 -> 16진수
- 0~9 의 기호(문자)에 a,b,c,d,e,f 6개의 기호(문자)를 더 추가해서 숫자를 표현하자
- 위에서 0~9가 10개 a~f가 6개 그래서 16진수다.
- 몫이 0이 될때까지 10진수를 16으로 나누고 나머지는 16진수표현으로 바꿔서 나눈 횟수의 자리수로 저장한다.
- (16으로 1회 나눈 나머지가 1이므로 나머지의 자리수는 1의 자리이고, 3번 나눴다면 자리수는 100의 자리이다.)
10진수 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
16진수 | 9 | a | b | c | d | e | f | 10 | 11 |
- 위 설명대로 10진수 20을 계산해보자. 20을 16으로 나누면 몫은 1, 나머지는 4이다. 몫은 계속 나누어주고, 현재 값은 4이다.
- 1을 16으로 나누면 몫은 0이고 나머지는 1이다. 이때 나머지 1은 2번 나누어서 10의 자리이다. 그러므로 4와 더하면 14이다.
- 10진수 20을 16진수로 변환한 값은 14이다.
- 이번에는 10진수 1000을 계산해보자. 1000을 16으로 나누면 몫은 62 나머지는 8 현재값은 8.
- 62를 16으로 나누면 몫은 3, 나머지는 14이고 14는 16진수로 e로 표현한다. 2번 나누었으므로 현재값은 e8.
- 3을 16으로 나누면 몫은 3, 나머지는 3. 3번 나누었으므로 현재 값은 3e8.
- 10진수 1000은 16진수로 3e8이다.
뭔가 간단하게 설명하고 싶은데 잘 안된것 같다. 중요한 것은 표현하는 기호(문자가) 6개 더 늘어난 것과 변환 규칙뿐이다.
10진수 -> 8진수
- 위의 16진수와 비슷한 개념이다. 16진수가 0~9에 6개를 더했다면 8진수는 0~9의 기호(문자) 중에서 2개를 뺀 것이다.
- 즉 0~7의 기호(문자) 로 수를 표현한다.
- 몫이 0이 될때까지 10진수를 8으로 나누고, 나머지는 나눈 횟수의 자리수로 저장한다.
10진수 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
8진수 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 |
- 10진수 16을 8진수로 변환해보자. 16진수에서 했던 계산과 동일하다.
- 16을 8로 나누면 몫은 2, 나머지는 0이고 나눈 횟수는 1회이므로 1의 자리는 현재 0.
- 2를 8로 나누면 몫은 0, 나머지는 2이고 나눈 횟수는 2회이므로 10의 자리는 2.
- 1의자리와 10의 자리를 더하면 20. 20이 10진수 16이다.
- 10진수 1000을 8진수로 변환.
- 1000 나눗셈 1회: 몫 125, 나머지 0 - 값 0
- 125 나눗셈 2회: 몫 15, 나머지 5 - 값 50
- 15 나눗셈 3회: 몫 1, 나머지 7 - 값 750
- 1 나눗셈 4회: 몫 0, 나머지 1 - 값 1750
- 10진수 1000은 8진수로 1750이다.
16진수 <-> 2진수
- 16진수와 2진수는 조금 간단하다. 이유는 2진수 4bit로 16진수의 모든 수를 표현 가능하기 때문이다.
- 2진수 0000 은 16진수로 0이고 2진수 1111은 16진수로 f이다. 그래서 보통 1byte는 8bit니까 1byte를 16진수로 표시하기 편하다.
- char형 변수에 10진수 13이라는 값이 들어가 있다고 해보자. 2진수로는 0000 1101 이다. 이걸 16진수로 바꾸면 왼쪽 4자리, 오른쪽 4자리로 나누어서 표시하면 된다. 왼쪽 4자리 0000은 16진수 0이고, 오른쪽 4자리 1101은 16진수로 d이다.
- 2진수 0000 1101은 16진수 0d 표시 할 수 있다. 16진수는 보통 앞에 0x를 붙이므로 0x0d라고 보면 되고 앞의 0은 생략이 가능하므로 보통 0xd라고 표시한다.
16진수 | 8 | 9 | a | b | c | d | e | f | 10 |
2진수 | 1000 | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 | 0001 0000 |
- 크게 설명한 것은 없고, 위에 설명한대로 2진수를 16진수로 서로 변환할때는 4bit씩 나누어서 계산하는 것이 좋다.
- 나머지 2 진수에서 8진수 변환 등등 도 개념은 다 비슷하다.
- 그리고 2진수에서 8, 16으로 바로 변환하는 것이 어렵다면 10진수로 변환 후 다시 계산하면 사람이 이해하기 더 쉽다.
- 역시 알고 있는 것과 설명하는 건 참 다르다.