[42서울] ft_printf 구현 (한 문장으로 구현하는 이진수 보수 연산)

2024. 6. 21. 19:46·대외활동/42서울
728x90
반응형

서론

과제 이름에서 알 수 있듯이 printf 함수를 구현하는 과제이다. 당연히 printf 함수의 모든 기능을 구현하는 것은 아니고, 문자열 표준 출력과 서식 지정자와 같은 대표적인 기능을 구현하게 된다. 본 과제에서는 va_arg 관련 함수에 대하여 배울 수 있고, 서식 지정자를 어떻게 처리할지에 대해서도 고민해 보며 코딩 실력을 기를 수 있다.

구현

ft_printf

구현한 ft_printf 함수의 메인 로직에 해당하는 두 함수이다. ft_printf 함수에서는 입력받은 문자열을 순서대로 while 루프를 돌아 서식지정자('%')가 아니라면 문자를 하나씩 출력하고, 서식지정자라면 그 뒤에 오는 문자에 따라서 행동을 지정한다. 이때 입력받은 va_list 구조체의 주소를 ft_format_conversion으로 전달한다. 이전 과제를 구현하면서 배웠듯이 주소를 다음 함수로 넘겨야 한다. 그렇지 않으면 변수 ap에 대한 복사본이 호출한 함수에서 사용되어 ft_printf 함수 내에서 va_arg를 통한 va_list ap의 다음 노드 이동이 일어나지 않게 된다. ft_format_conversion 함수에서는 각 서식 지정자에 맞는 함수를 호출하여 서식이 변환된 문자열을 출력한다. 이중 ft_prf_itohex 함수는 다음과 같다.

 

ft_prf_itohex

num += 2L * 16 * 16 * 16 * 16 * 16 * 16 * 16 * 16; 부분이 눈에 들어올 것이다. 이 코드는 대학교 1학년 때 수업 중 배웠던 c의 변수 저장 방식에서 영감을 받아서 작성하였다. 먼저 itohex 함수에서 인자로 들어오는 숫자가 음수라면 그 숫자에 대한 이진수 보수를 출력해야 한다. 2의 보수에 대하여 예시를 통해 살펴보자.

 

한 문장으로 구현하는 이진수 보수 연산

저장 공간으로 4비트를 사용한다고 가정하자(저장 범위 -7~8, 맨 왼쪽 비트는 양수/음수 부호 표현).

 

숫자 -1은 다음과 같이 저장된다.

0001의 보수: 각 비트에 대해 not 연산 -> 1 더하기 -> 맨 왼쪽 비트 음수 부호로 바꾸기

0001 -> 0110 -> 0111 -> 1111

1111

 

여기서 1을 더한다면 10000이 되는데 저장 공간이 4비트이므로 맨 왼쪽 비트가 버려져 저장 공간에 0000이 담기게 된다. 이 연산에서 부호 비트도 변경되면서 -1의 이진수에 1을 더했을 때 0에 해당하는 값으로 모든 비트가 자연스럽게 연산되는 것을 알 수 있다.

저장 공간이 4비트라면 10000, 0000 모두 0을 나타낸다는 것을 기억하자.

 

숫자 8은 다음과 같이 저장된다.

0111

 

숫자 8에서 1을 더한다면 어떻게 될까?

0111 + 1 -> 1000

저장 공간의 값은 -7을 나타낸다. 이를 통해 저장 공간의 양수 값 끝 범위인 8에서 1을 더했을 때 저장 공간의 음수 값 끝 범위인 -7이 된다는 것을 알 수 있다.

 

위 두 예시를 통하여 0에서부터 1을 계속 더하면 아래와 같이 숫자들이 순환하는 특징을 알 수 있다.

0 1 2 3 4 5 6 7 8 -7 -6 -5 -4 -3 -2 -1 0

 

이 특징과 부호 비트가 없는 경우의 값들을 활용하여 음수 값을 이진수의 보수로 출력하기 위한 값을 구하는 식을 작성할 수 있다.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 -7 -6 -5 -4 -3 -2 -1

 

위는 부호 비트를 제외한 4개의 비트가 표현하는 값(0000~1111, 1씩 증가),

아래는 부호 비트를 포함한 4개의 비트가 표현하는 값(0000~1111, 1씩 증가)이다.

음수를 이진수 보수로 출력하고 싶은 경우 위의 값으로 대치해서 이진수로 바꾸어 출력하면 된다.

  • 양수인 경우: 그대로 이진수로 바꾸어 출력
  • 음수인 경우: (부호 비트 제거, 16에서 출력하고자 하는 값 빼주기) 변경 후 이진수로 바꾸어 출력

이 내용을 보고 위에 작성한 코드를 보면 이해가 갈 것이다.

int	ft_prf_itohex(int n)
{
	unsigned long long	num;

	num = n;
	if (n < 0)
		num += 2L * 16 * 16 * 16 * 16 * 16 * 16 * 16 * 16;
}

 

후기

위 코드를 작성하고 동료평가 때 관심을 가지는 사람들이 많았어서 나름 만족스러웠다. 코드를 설명하는 실력도 늘은 것 같고 여러모로 도움이 되는 과제였다. 아래 내용은 앞서 설명한 내용 이외에도 새로 배우게 된 내용이다.

 

이전에 작성한 get_next_line 과제의 헤더파일
이번에 작성한 ft_printf 과제의 헤더파일

헤더파일의 경우 ft_printf 함수와 나머지 유틸 함수를 분리하여 각자 다른 헤더 파일에 담았다. 이전에 작성했던 get_next_line 헤더파일과 대비하여 깔끔해진 모습이다. ft_printf 함수를 사용하기 위해 헤더파일을 선언하면 이외의 불필요한 함수들은 노출되지 않는다.

 

이후 과제도 열심히 구현해보자!

 

 

728x90
반응형

'대외활동 > 42서울' 카테고리의 다른 글

[42서울] so_long 맵 유효성 검사(BFS)  (0) 2024.07.22
[42서울] get_next_line 구현 (메모리 누수 잡기, 구현 tip)  (1) 2024.07.21
[42서울] Libft 함수 정리와 후기  (0) 2024.03.20
[42서울] push_swap 그리디 알고리즘  (2) 2024.03.04
[42서울] Born2beroot 개념 정리 2  (0) 2024.03.04
'대외활동/42서울' 카테고리의 다른 글
  • [42서울] so_long 맵 유효성 검사(BFS)
  • [42서울] get_next_line 구현 (메모리 누수 잡기, 구현 tip)
  • [42서울] Libft 함수 정리와 후기
  • [42서울] push_swap 그리디 알고리즘
dev_ares
dev_ares
대학에서 컴퓨터공학을 전공하고 있는 학생입니다.
    반응형
    250x250
  • dev_ares
    노트
    dev_ares
  • 전체
    오늘
    어제
    • 분류 전체보기 (188)
      • IT 트랜드 (2)
      • 백엔드 (18)
        • Java + Spring (8)
        • Kotlin + Spring (5)
        • 백엔드 (5)
      • 프론트엔드 (1)
        • React (1)
      • 대외활동 (17)
        • 42서울 (17)
      • 백준 (6)
        • Java (2)
        • C++ (3)
      • 전공 (121)
        • 객체지향프로그래밍 (17)
        • 자료구조 (23)
        • 리눅스시스템관리 (16)
        • 컴퓨터구조 (25)
        • 네트워크 (25)
        • 데이터베이스 (15)
        • 기타 전공 (0)
      • 프로그래밍 언어 (18)
        • Java (5)
        • Swift (4)
        • C++ (1)
        • Kotlin (8)
      • 기타 (4)
      • 공군 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코틀린
    티스토리챌린지
    자바
    단일 사이클
    추가 문제
    명령어
    상속
    C++
    오블완
    반복자
    42서울
    컴퓨터구조
    컴공 포트폴리오
    자료구조
    컴퓨터 구조 및 설계
    데이터패스
    메모리 계층 구조
    사설 문제
    리눅스
    백준
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
dev_ares
[42서울] ft_printf 구현 (한 문장으로 구현하는 이진수 보수 연산)
상단으로

티스토리툴바