과 같지 않습니다. 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;
}
[이유는'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) –
입력 값이 충분히 작 으면 테스트 (''fabs (val-atof()) <= EPSILON)'는 의미가 없습니다. 예를 들어, 입력으로 0.000000009는 0으로 출력됩니다 ('% f'는 소수점 6 자리까지 출력하기 때문입니다). 코드가 9를 4로 변환했는지는 중요하지 않습니다. 절대 차이가 여전히 EPSILON보다 작습니다 . '(fabs (val-atof)/max (fabs (val), fabs (atof (s))) <= EPSILON)'과 같은 상대적인 차이를 사용해야합니다. –
Pedantic note :'while ((c = * s ++)! = '\ 0') {'는 오버 플로우로부터 보호하지 못했습니다. – chux