2015-02-03 11 views
0

과 같지 않습니다. atof_beta.i라는 atof 함수를 작성했지만 그 결과는 atof의 결과와 같지 않습니다. 예atof_beta라는 atof에서 구현되었지만 결과는 atof

: 입력 : 1111111111111111111111111111111111111111111111111111111111111111111111111111111111

출력 (팹 (브로-으로 atof (S)) = < EPSILON)은 0과 동일.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <limits.h> 
#include <float.h> 
#include <math.h> 

double check_overflow(double val) 
{ 
    if (val > DBL_MAX){ 
     return DBL_MAX; 
    }else if (val < DBL_MIN){ 
     return DBL_MIN; 
    } 
    return val; 
} 


double get_exp(char *s) 
{ 
    double exp = 10; 
    int num = 0x00; 
    char c = *s; 

    if (c == '-'){ 
     exp = 0.1; 
     s++; 
    }else if (c == '+'){ 
     s++; 
    } 

    while ((c = *s++) != '\0'){ 
     if ((c >= '0') && (c <= '9')){ 
      num = num*10 + c - '0'; 
     } 
     else{ 
      return 0x01; 
     } 
    } 

    double tmp = 0x01; 
    while (num--){ 
     tmp *= exp; 
    } 

    return tmp; 
} 

double atof_beta(char *s) 
{ 
    double integer = 0x00; 
    double fraction = 0x00; 
    int sign = 0x01; 
    int fraction_flag = 0x00; 
    double divisor = 0x01; 
    double exp = 0x01; 

    char c = *s; 

    if (c == '-'){ 
     sign = -1; 
     s++; 
    }else if (c == '+'){ 
     sign = 1; 
     s++; 
    } 

    while ((c = (*s++)) != '\0'){ 
     if ((c >= '0') && (c <= '9')){ 
      if (!fraction_flag){ 
       integer = integer*10 + (c -'0'); 
      }else{ 
       fraction = fraction*10 + c -'0'; 
       divisor *= 10; 
      } 
     }else if (c == '.'){ 
      fraction_flag = 0x01; 
     }else if ((c == 'e') || (c == 'E')){ 
      exp = get_exp(s); 
      break; 
     }else{ 
      break; 
     } 
    } 

    integer = check_overflow(integer); 
    fraction = check_overflow(fraction); 
    exp = check_overflow(exp); 
    double val = sign*((integer + (fraction/divisor))*exp); 
    return check_overflow(val); 
} 

#define EPSILON 1e-6 
void main() 
{ 
    char s[1024], *p; 
    double val; 

    while(1) 
    { 
     printf("enter string : "); 
     fgets(s, sizeof(s), stdin); 
     if ((p = strchr(s, '\n')) != NULL) { 
      *p = '\0'; /* Remove newline */ 
     } 
     puts(s); /* No need to cast */ 
     val = atof_beta(s); 
     printf("\nfinal value : %lf, %lf, %d\n", val, atof(s), (fabs(val-atof(s)) <= EPSILON)); 
    } 

    return; 
} 
+1

[이유는'gets()'함수가 위험합니까?] (http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not) -be-used) 및 [무엇을 사용해야합니까? 'main()'return C 및 C++] (http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c/18721336#18721336) –

+1

입력 값이 충분히 작 으면 테스트 (''fabs (val-atof()) <= EPSILON)'는 의미가 없습니다. 예를 들어, 입력으로 0.000000009는 0으로 출력됩니다 ('% f'는 소수점 6 자리까지 출력하기 때문입니다). 코드가 9를 4로 변환했는지는 중요하지 않습니다. 절대 차이가 여전히 EPSILON보다 작습니다 . '(fabs (val-atof)/max (fabs (val), fabs (atof (s))) <= EPSILON)'과 같은 상대적인 차이를 사용해야합니다. –

+0

Pedantic note :'while ((c = * s ++)! = '\ 0') {'는 오버 플로우로부터 보호하지 못했습니다. – chux

답변

1

이 잘못 : 하나의 char에 대한

char *s; 
... 
printf("enter string : "); 
s = (char *)malloc(sizeof(char)); 
gets((char *)s); 
puts((const char *)s); 

당신의 공간을 예약하지만 당신은 또한 gets는 C99가 사용됩니다 및 C11 그것을 제거주의, 문자열을 원하는, 내가 fgets을 제안 :

char s[32], *p; 
... 
printf("enter string : "); 
/* No need to malloc */ 
fgets(s, sizeof s, stdin); 
if ((p = strchr(s, '\n')) != NULL) { 
    *p = '\0'; /* Remove newline */ 
} 
puts(s); /* No need to cast */ 
+0

고마워요! 제가 다시 썼습니다. –