2진수값을 콘솔에 10진수 숫자로 표시하는 원리는?

yjc99의 이미지

갑자기 궁금하게 생각되네요.

int i=2;
printf("%d",i);

이런식으로 i 값을 콘솔에 찍으면 '2'라는 문자로 찍히는데, 이 과정에서 궁금한점이 있는데요.
i값은 실질적으로 비트배열인데(00000010) 이것을 콘솔에 찍을때는 십진수로 변환이 되어서 '2'라는 숫자문자가 찍혀야 하는데, 어떻게 하는건지 의문이 듭니다.

1바이트만이라면 255가지의 숫자문자매핑태이블을 만들어 놓는다고 해도, 4byte, 8byte 그 이상도 있는데 이는 불가능한거고...
어떻게 하는건지 추측이 잘 안되네요.

DarkSide의 이미지

컴파일러가 2에 해당하는 아스키 코드를 리턴해서 화면에 프린트합니다.

yjc99의 이미지

답변 감사합니다.
근데 제가 궁금한건 비트배열이 십진수로 어떻게 변환되는지에 대한 질문입니다.
가령
256이라는 숫자가 있으면, 비트매열로 100000000(0x100) 인데 이 값을 콘솔에 찍기 위한 과정으로,
우선적으로 비트매열이 256이라는 10진수 숫자인것을 알아야 하고,
그 이후에 이를 화면에 찍을때는 숫자를 문자로 바꾸기 위해서 말씀하신대로 각 자리수의 digit 마다 아스키코드값으로 변환해서 찍어줄것 같습니다.

여기서 궁금한게 100000000 이라는 비트매열이 십진수 256이라는것을 어떻게 , 언제 계산하는지가 궁금하네요. 다른 말로 하면 비트배열을 아스키코드값배열로 변환하는 알고리즘이 따로 있는것인지에 대한 질문이기도 합니다.

 의 이미지

간단합니다.

직접 10진법에서 2진법으로 변환할 때를 생각해보세요.
10진법에서 2로 나눈 몫과 나머지를 구하는 걸 반복하면 2진법에서의 산술 없이도 2진법으로 변환할 수 있죠.
10진법으로 변환할 때도 마찬가지입니다.

코드로 말씀드리는 편이 가장 빠르겠네요.

void my_itoa(unsigned int integer, char *array) {
	size_t i = 0, j = 0;
	char tmp;
	do {
		array[i++] = (integer % 10) + '0';
	} while (integer /= 10);
	array[i--] = '\0';
	while (j < i) {
		tmp = array[i];
		array[i--] = array[j];
		array[j++] = tmp;
	}
}

Disclaimer:
1. array로는 충분한 길이의 버퍼가 들어온다고 가정합니다. 원래 함부로 이러면 안되는 거 아는데, 귀찮아요.
2. integer가 int가 아니라 unsigned int인데, 일부러 그런 겁니다. int를 받으면서 이식성 있는 10진법-2진법 변환 코드를 짜는 건 좀 성가신 문제가 있어요. 원래 C언어에서 부호 있는 정수라는 게 좀 그렇고 그런 면이 있는데, 일례로는 (아직도 답이 안 달리고 있는) https://kldp.org/node/157873 같은 질문들이 있지요.

ifree의 이미지

십진수로 소스에 표현되어 있지만, 십진수인지 여부를 기계가 알 필요는 없습니다. 값만 알면 되죠. 이 값을 콘솔에 표현하라는 명령을 받으면, 아래 분이 설명한 이진수를 십진수로 변환하는 방식에 따라 각 자리의 수를 알아 내고, 이 수에 해당하는 아스키 코드를 화면에 송출하는 것입니다.

...!의 이미지

8bit 부호 없는 정수 타입을 예로 들어보지요. bit수가 많아져도, 부호가 있어도, floating point number를 사용해도 크게 달라지지 않습니다. 필요한 사항을 하나씩 더 고려하기만 하면 됩니다.

주어진 2진수 배열을 x라고 부릅시다.
8자리 2진수가 표현할 수 있는 수는 0부터 2^8 = 256 입니다.
그럼 10진수로 표현했을 때에는 최대 세 자리로 표현되겠네요.
즉 8bit 부호 없는 정수 타입은 세 자리만 고려하면 됩니다.
100의 자리 수는 x를 100으로 나눈 몫입니다.
10의 자리 수는 x를 100으로 나머지를 10으로 나눈 몫입니다.
1의 자리수는 x를 100으로 나머지를 10으로 나눈 나머지입니다.
(실제 컴퓨터에서 이진수 배열 x를 100으로 나누거나 10으로 나누는 일은 bit 연산을 통해서 쉽게 할 수 있습니다. 검색해보시면 쉽게 좋은 설명을 찾을 수 있을겁니다.)

어째서 이렇게 되는 지는 n-진수라는 말의 뜻(정의)을 알면 그리 어렵지 않게 알 수 있습니다.
x_2, x_1, x_0 이라는 수열이 있다고 하지요.
이게 어떤 수의 n-진수 표현이라면 각 x_2, x_1, x_0 가 0 부터 n - 1 까지의 수 중 하나인 겁니다.
그리고 이 수열이 나타내는 수는 x_2 * n^2 + x_1 * n^1 + x_0 * n^0 입니다.
이진수 100000000 을 계산해볼까요? 1 * 2^8 + 0 + ... = 256 입니다.
그럼 10진수로 표현한 각 자리의 수를 구하는 위의 방법은 어떻게 나온 걸까요?
그냥 위 식 x_2 * n^2 + x_1 * n^1 + x_0 * n^0 을 보면 알지요. 나눗셈의 몫과 나머지의 정의에 따라 너무 당연합니다. 혹시 당연하지 않으시면 나눗셈의 의미에 대해서 곰곰히 생각해보시고 "x 나누기 y의 몫은 a 나머지는 b" 라는 말이 "x = a * y + b and 0 < b < y" 와 같은 뜻이라는 것을 이해하시면 아마 당연하게 느껴지실 겁니다.

그리고 참고로 저는 고등학교 수학 시간에 이걸 공부한 기억이 나네요. 아마 ... yjc99님도 배우셨을 겁니다 :)

Necromancer의 이미지

굳이 2진수를 10진수로 변환할 필요 없습니다.

콘솔에 출력되는 텍스트는 ASCII 코드이므로, 주어진 숫자를 10진수로 표시했을때의 각 자리 숫자를 알아낸다음 이것을 10진수 ASCII문자열로 바꾸면 됩니다.

1) 10으로 나눈 나머지 구한다.
2) 구해진 나머지를 0~9 문자에 대응되는 ASCII 코드로 변환한다.
-> 0x30만 더하면 끝입니다. 0~9를 표시하는 문자의 ASCII코드는 0x30~0x39 입니다.
3) 10으로 나눈 몫을 구한 후 다시 1로 돌아간다. 단, 10으로 나눈 몫이 0이면 4)로 넘김.
-> 10으로 나눈 몫은 10진수 윗자리수를 구하는데 씁니다.
4) 1~3에서 구한 각 자릿수 문자를 역순 정렬한다. (10진수 각 자리별 숫자가 아랫자리부터 나오기 때문입니다)
5) 출력한다.

입니다.

Written By the Black Knight of Destruction

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.