[ft_atoi] underflow, overflow처리 관련 삽질

duckkuri·2020년 10월 8일
0

42Seoul_Libft_Story

목록 보기
1/22

경과 1

ft_atoi 구현을 위해 stdlib.h헤더의 atoi()함수를 사용하여 다음과 같이 여러가지 값으로 테스트 해보았다.

	printf("return(MIN) : %d\n", atoi("-2147483648"));	 // -2147483648
	printf("return(MAX) : %d\n", atoi("2147483647"));	// 2147483647
	printf("return(MIN-1) : %d\n", INT_MAX);	// 2147483647
	printf("return(MIN-1) : %d\n", atoi("-2147483649")); // 2147483647
	printf("return(MAX+1) : %d\n", INT_MIN); // -2147483648
	printf("return(MAX+1) : %d\n", atoi("2147483648"));	// -2147483648
	printf("return(123aa) : %d\n", atoi("123aa"));	 // 123
	printf("return(123 123) : %d\n", atoi("123 123"));	 // 123
    printf("return(--123) : %d\n", atoi("--123"));	 // 0
    printf("return(-+-123) : %d\n", atoi("-+-123"));	 // 0
    printf("return(++123) : %d\n", atoi("++123"));	 // 0
    printf("return(+-123) : %d\n", atoi("+-123"));	 // 0
    printf("return(-+123) : %d\n", atoi("-+123"));	 // 0

경과 2

테스트 후 예외 처리 해야하는 부분을 체크하였다.

  • 부호가 2개 이상인 경우 0으로 처리할것
  • 숫자를 제외한 문자열이 나오는경우 그 전까지의 숫자들만 인식 하는것
  • return type의 int형이 넘는 문자열 숫자를 입력하는 경우(오버플로우) INT_MIN값으로 리턴되는것
  • return type의 int형이 보다 낮은 문자열 숫자를 입력하는 경우(언더플로우) MAX_MIN값으로 리턴되는것

🚨문제 상황

언더플로우와 오버플로우에 대한 처리를 어떻게 할까

경과 3

언더플로우 오버플로우때의 규칙을 찾기위해 다음과 같은 규칙을 찾았다
엄청난 삽질 및 뻘짓

atoi(x) 라고 했을때,

x > INT_MAX 인 경우

  • x / INT_MAX 가 홀수인 경우 리턴값
    (INT_MAX - (x / INT_MAX) - 1) + (x % INT_MAX)

  • x / INT_MAX 가 짝수인 경우 리턴값
    ((x / INT_MAX) * -1) + (x % INT_MAX)

x < INT_MIN 인 경우

  • x / INT_MIN 가 홀수이며, 나머지가 없는 경우 리턴값
    INT_MIN

  • x / INT_MIN 가 홀수이며, 나머지가 있는 경우 리턴값
    MAX + (x % min + 1)

  • x / INT_MIN 가 짝수인 경우 리턴값
    x % min

경과 4

규칙을 다 찾은 후 기쁨도 잠시, 세운 식들을 살펴보면서 무언가 잘못돌아가고 있는것이 느껴지기 시작했다.
'뭔가.. 복잡한데 진짜 이렇게까지 예외처리를 해야하는 걸까..'라는 생각이 들었다. 그제서야 서둘러 slack에 검색하여 다른 사람들이 올린 질문과 답변을 살펴보았다.

경과 5

친절한 카뎃 quartzmhouppin의 답변에 의해 해답을 찾을 수있었다.

  • man에 의하면 atoi()의 오류처리는 따로 하지 않는다고 한다.
  • atoi() 함수는 libc에 의해 stdtol()를 내부로 돌려서 결과값을 리턴하는 방식을 가졌다.
  • atoi()의 리턴 타입은 int, strtol()의 리턴 타입은 long 이다.
  • atoi()에서 나오는 언더플로우/오버플로우의 리턴값은 strtol()에서 나온 결과값을 처리하는 과정에서 나오는 ERANGE 오류이다.
  • strtol()함수에 오버플로우 값이 들어오면 LONG_MAX, 언더플로우 값이 들어오면 LONG_MIN을 리턴한다.
  • atoi()함수에 LONG 오버플로우 값이 들어오면 -1, 언더플로우 값이 들어오면 0을 리턴한다.
printf("return(MAX) : %ld\n", LONG_MAX);	 // 9223372036854775807
printf("return(MIN) : %ld\n", LONG_MIN);	// -9223372036854775808
printf("return(-6442) : %d\n", atoi("-6442"));	// -6442
printf("return(-6442) : %ld\n", strtol("-6442",NULL,10));	// -6442
printf("return(MAX) : %ld\n", strtol("9223372036854775807",NULL,10));	// 9223372036854775807
printf("return(MAX+1) : %ld\n", strtol("9223372036854775808",NULL,10));	// 9223372036854775807
printf("return(MIN) : %ld\n", strtol("-9223372036854775808",NULL,10));	// -9223372036854775808
printf("return(MIN-1) : %ld\n", strtol("-9223372036854775809",NULL,10));	// -9223372036854775808
printf("return(LONGMAX) : %d\n", atoi("9223372036854775807"));	// -1
printf("return(LONGMIN) : %d\n", atoi("-9223372036854775809"));	// 0

결론 : libft에서는 굳이 이러한 오버플로우/언더플로우 처리값까진 신경쓰지 않으므로 무시해도 된다.😂

profile
😤 Today I Learned

0개의 댓글