📄 atof.h
字号:
/****************************************************************
Convert floating decimal to binary 02-17-86
Copyright 1986 Software Development Systems, Inc.
All rights reserved
****************************************************************/
#define EBITS (sizeof(FLT)==4? 6: 9)
/****************************************************************
DIGLIMIT represents the maximum number of digits
considered significant, beyond which digits are
altered to zeros to prevent overflows.
****************************************************************/
#define DIGLIMIT (sizeof(FLT)==4? 9: 17)
#define EXPLIMIT (((32767-9)/10)*10) /* limit due to int holding exponent */
/****************************************************************
Convert the characters at (*pp) to a floating point
number, storing it at idst. Leading white space is
not accepted. If "width" is nonnegative, no more than
"width" characters will be used. Leave (*pp) pointing
to the first character not used by the conversion.
If no characters are accepted (*pp) will be unchanged,
*idst will be zero and zero will be returned.
Otherwise:
Return *idst When
------ ----- --------------
0 value no underflow or gross overflow was detected (but
the value may still be an infinity representing
an overflow)
1 undef gross overflow detected for positive number
-1 undef gross overflow detected for negative number
2 0.0 underflow was detected
???infinity/nan ???monotonic ???cvb:cvd:cvb same as
input number cases,etc.
****************************************************************/
#define next_p if ( width > 0 ) --width; \
++p
int ATOF(FLT *idst,
char **pp,
int width )
{
int nzdigits = 0; char valid = 0;
rchar *p = *pp; rint sgn = 0, esgn = 0, exp = 0, expadj = 0;
uint i; rchar ovfl = 0, undfl = 0;
ZERO( idst );
if ( width && (*p == '+' || *p == '-') )
{
/********************************************************
Optional sign.
********************************************************/
if ( *p == '-' ) sgn = 1;
next_p; }
while ( width && *p >= '0' && *p <= '9' )
{
/********************************************************
Optional integer digits.
********************************************************/
valid = 1;
if ( nzdigits || *p != '0' ) ++nzdigits;
if ( nzdigits > DIGLIMIT )
{ /* pretend digit is '0' */
if ( expadj < EXPLIMIT ) ++expadj;
else ovfl = 1; }
else
{
MUL( idst, idst, &tens[0] );
ADD( idst, idst, &ones[ *p - '0' ] );
}
next_p;
}
if ( width && *p == '.' )
{
/********************************************************
Optional fraction.
********************************************************/
next_p;
while ( width && *p >= '0' && *p <= '9' )
{
valid = 1;
if ( nzdigits || *p != '0' ) ++nzdigits;
if ( nzdigits > DIGLIMIT )
{ /* ignore digit */
--nzdigits;
}
else
{
if ( expadj > -EXPLIMIT ) --expadj;
else undfl = 1; /* will reset undfl if never nzdigits */
if ( nzdigits )
{
MUL( idst, idst, &tens[0] );
ADD( idst, idst, &ones[ *p - '0' ] );
}
}
next_p;
}
}
if ( !valid ) return 0; /* require at least one digit */
if ( sgn ) NEG( idst, idst );
if ( width && (*p == 'e' || *p == 'E') )
{
/********************************************************
Optional exponent.
********************************************************/
next_p;
if ( width && (*p == '+' || *p == '-') )
{
if ( *p == '-' ) esgn = 1;
next_p;
}
if ( width && *p >= '0' && *p <= '9' )
{
while ( width && *p >= '0' && *p <= '9' )
{
if ( exp > (EXPLIMIT/10) )
{
if ( esgn ) undfl = 1;
else ovfl = 1;
}
else
{
exp *= 10;
exp += *p - '0';
}
next_p;
}
if ( esgn ) exp = -exp;
}
else
{
ZERO( idst );
return 0;
}
} /* require exponent after an 'e' */
/****************************************************************
If there were no nonzero digits then the number value is
zero and any underflow indication was incorrect and
an indication of an overflowed exponent is irrelevant.
****************************************************************/
if ( !nzdigits ) undfl = ovfl = expadj = exp = 0;
/****************************************************************
Adjust the exponent by the number of accepted
fractional digits.
****************************************************************/
if ( (long)exp + expadj > EXPLIMIT ) exp = EXPLIMIT;
else if ( (long)exp + expadj < -EXPLIMIT ) exp = -EXPLIMIT;
else exp += expadj;
esgn = 0;
if ( exp < 0 )
{
esgn = 1;
exp = -exp;
}
if ( exp >= (1 << EBITS) )
{
if ( esgn ) undfl = 1;
else ovfl = 1;
}
else
{
for ( i = 0; i <= EBITS; ++i )
{
if ( exp & (1 << i) )
{
if ( esgn ) DIV( idst, idst, &tens[i] );
else MUL( idst, idst, &tens[i] );
}
}
}
*pp = p;
if ( ovfl ) return sgn? -1: 1;
if ( undfl ) ZERO( idst );
if ( TST( idst )==0 && nzdigits ) return 2;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -