85 lines
2.3 KiB
C
85 lines
2.3 KiB
C
/* xxstod.h -- _[W]Sto[d f ld] common functionality */
|
|
|
|
#pragma warning(disable: 4210)
|
|
|
|
/* macros */
|
|
#define ACSIZE 3 /* size of extended-precision accumulators */
|
|
|
|
#define D16TO7 FLIT(268435456.0) /* 16^7 */
|
|
#define D10TO9 FLIT(1e9) /* 10^9 */
|
|
#define NLONG ((FBITS + 27) / 28) /* 7 * NLONG == max hexadecimal digits */
|
|
|
|
/*
|
|
FTYPE _Stodx(const CTYPE *s, CTYPE **endptr, long pten, int *perr)
|
|
*/
|
|
{ /* convert string to FTYPE, with checking */
|
|
FTYPE x;
|
|
long lo[NLONG + 1];
|
|
const CTYPE *s0 = s;
|
|
int code = CNAME(Stopfx)(&s, endptr);
|
|
const int neg = code & FL_NEG;
|
|
|
|
extern _CRTIMP2_PURE FTYPE __CLRCALL_PURE_OR_CDECL FNAME(Dtento)(FTYPE *, long, int *);
|
|
|
|
if (perr != 0)
|
|
*perr = 0;
|
|
if ((code &= ~FL_NEG) == FL_DEC)
|
|
{ /* parse decimal format */
|
|
const int nlo = CNAME(Stoflt)(s0, s, endptr, lo, NLONG);
|
|
FTYPE xpx[ACSIZE], xpf[ACSIZE];
|
|
int i;
|
|
|
|
FNAME(Xp_setw)(xpf, ACSIZE, D10TO9);
|
|
if (nlo == 0)
|
|
FNAME(Xp_setw)(xpx, ACSIZE, 0.0);
|
|
else
|
|
for (i = 1, FNAME(Xp_setn)(xpx, ACSIZE, lo[1]); i < nlo; )
|
|
{ /* x = x * D10TO9 + (FTYPE)lo[++i] */
|
|
FTYPE xpa[ACSIZE];
|
|
FTYPE xpt[ACSIZE * 2];
|
|
|
|
FNAME(Xp_mulx)(xpx, ACSIZE, xpf, ACSIZE, xpt);
|
|
FNAME(Xp_setn)(xpa, ACSIZE, lo[++i]);
|
|
FNAME(Xp_addx)(xpx, ACSIZE, xpa, ACSIZE);
|
|
}
|
|
x = FNAME(Dtento)(xpx, pten + lo[0], perr);
|
|
}
|
|
else if (code == FL_HEX)
|
|
{ /* parse hexadecimal format */
|
|
const int nlo = CNAME(Stoxflt)(s0, s, endptr, lo, NLONG);
|
|
FTYPE xpx[ACSIZE], xpf[ACSIZE];
|
|
int i;
|
|
|
|
FNAME(Xp_setw)(xpf, ACSIZE, D16TO7);
|
|
if (nlo == 0)
|
|
FNAME(Xp_setw)(xpx, ACSIZE, 0.0);
|
|
else
|
|
for (i = 1, FNAME(Xp_setn)(xpx, ACSIZE, lo[1]); i < nlo; )
|
|
{ /* x = x * D10TO9 + (FTYPE)lo[++i] */
|
|
FTYPE xpa[ACSIZE];
|
|
FTYPE xpt[ACSIZE * 2];
|
|
|
|
FNAME(Xp_mulx)(xpx, ACSIZE, xpf, ACSIZE, xpt);
|
|
FNAME(Xp_setn)(xpa, ACSIZE, lo[++i]);
|
|
FNAME(Xp_addx)(xpx, ACSIZE, xpa, ACSIZE);
|
|
}
|
|
x = FNAME(Dtento)(xpx, pten, perr);
|
|
FNAME(Dscale)(&x, lo[0]);
|
|
}
|
|
else if (code == FL_INF)
|
|
x = FCONST(Inf);
|
|
else if (code == FL_NAN)
|
|
x = FCONST(Nan);
|
|
else
|
|
x = FLIT(0.0); /* code == FL_ERR */
|
|
|
|
if (neg)
|
|
FNEGATE(x);
|
|
return (x);
|
|
}
|
|
|
|
/*
|
|
* Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED.
|
|
* Consult your license regarding permissions and restrictions.
|
|
V6.00:0009 */
|