/**************************************************************** * * The author of this software is David M. Gay. * * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. *
***************************************************************/
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
/* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision * before invoking strtod or dtoa. If the machine uses (the equivalent * of) Intel 80x87 arithmetic, the call * _control87(PC_53, MCW_PC); * does this with many compilers. Whether this or another call is * appropriate depends on the compiler; for this to work, it may be * necessary to #include "float.h" or another system-dependent header * file.
*/
/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. * * This strtod returns a nearest machine number to the input decimal * string (or sets errno to ERANGE). With IEEE arithmetic, ties are * broken by the IEEE round-even rule. Otherwise ties are broken by * biased rounding (add half and chop). * * Inspired loosely by William D. Clinger's paper "How to Read Floating * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. * * Modifications: * * 1. We only require IEEE, IBM, or VAX double-precision * arithmetic (not IEEE double-extended). * 2. We get by with floating-point arithmetic in a case that * Clinger missed -- when we're computing d * 10^n * for a small integer d and the integer n is not too * much larger than 22 (the maximum integer k for which * we can represent 10^k exactly), we may be able to * compute (d*10^k) * 10^(e-k) with just one roundoff. * 3. Rather than a bit-at-a-time adjustment of the binary * result in the hard case, we use floating-point * arithmetic to determine the adjustment to within * one bit; only in really hard cases do we need to * compute a second residual. * 4. Because of 3., we don't need a large table of powers of 10 * for ten-to-e (just some small tables, e.g. of 10^k * for 0 <= k <= 22).
*/
/* * #define IEEE_8087 for IEEE-arithmetic machines where the least * significant byte has the lowest address. * #define IEEE_MC68k for IEEE-arithmetic machines where the most * significant byte has the lowest address. * #define Long int on machines with 32-bit ints and 64-bit longs. * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic (D_floating). * #define No_leftright to omit left-right logic in fast floating-point * computation of dtoa. This will cause dtoa modes 4 and 5 to be * treated the same as modes 2 and 3 for some inputs. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS * is also #defined, fegetround() will be queried for the rounding mode. * Note that both FLT_ROUNDS and fegetround() are specified by the C99 * standard (and are specified to be consistent, with fesetround() * affecting the value of FLT_ROUNDS), but that some (Linux) systems * do not work correctly in this regard, so using fegetround() is more * portable than using FLT_ROUNDS directly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and Honor_FLT_ROUNDS is not #defined. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines * that use extended-precision instructions to compute rounded * products and quotients) with IBM. * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic * that rounds toward +Infinity. * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased * rounding when the underlying floating-point arithmetic uses * unbiased rounding. This prevent using ordinary floating-point * arithmetic when the result could be computed with one rounding error. * #define Inaccurate_Divide for IEEE-format with correctly rounded * products but inaccurate quotients, e.g., for Intel i860. * #define NO_LONG_LONG on machines that do not have a "long long" * integer type (of >= 64 bits). On such machines, you can * #define Just_16 to store 16 bits per 32-bit Long when doing * high-precision integer arithmetic. Whether this speeds things * up or slows things down depends on the machine and the number * being converted. If long long is available and the name is * something other than "long long", #define Llong to be the name, * and if "unsigned Llong" does not work as an unsigned version of * Llong, #define #ULLong to be the corresponding unsigned type. * #define KR_headers for old-style C function headers. * #define Bad_float_h if your system lacks a float.h or if it does not * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked * directly -- and assumed always to succeed. Similarly, if you * want something other than the system's free() to be called to * recycle memory acquired from MALLOC, #define FREE to be the * name of the alternate routine. (FREE or free is only called in * pathological cases, e.g., in a dtoa call after a dtoa return in * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making * memory allocations from a private pool of memory when possible. * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, * unless #defined to be a different length. This default length * suffices to get rid of MALLOC calls except for unusual cases, * such as decimal-to-binary conversion of a very long string of * digits. The longest string dtoa can return is about 751 bytes * long. For conversions by strtod of strings of 800 digits and * all dtoa conversions in single-threaded executions with 8-byte * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte * pointers, PRIVATE_MEM >= 7112 appears adequate. * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK * #defined automatically on IEEE systems. On such systems, * when INFNAN_CHECK is #defined, strtod checks * for Infinity and NaN (case insensitively). On some systems * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 * appropriately -- to the most significant word of a quiet NaN. * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, * strtod also accepts (case insensitively) strings of the form * NaN(x), where x is a string of hexadecimal digits and spaces; * if there is only one string of hexadecimal digits, it is taken * for the 52 fraction bits of the resulting NaN; if there are two * or more strings of hex digits, the first is for the high 20 bits, * the second and subsequent for the low 32 bits, with intervening * white space ignored; but if this results in none of the 52 * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 * and NAN_WORD1 are used instead. * #define MULTIPLE_THREADS if the system offers preemptively scheduled * multiple threads. In this case, you must provide (or suitably * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed * in pow5mult, ensures lazy evaluation of only one copy of high * powers of 5; omitting this lock would introduce a small * probability of wasting memory, but would otherwise be harmless.) * You must also invoke freedtoa(s) to free the value s returned by * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that * avoids underflows on inputs whose result does not underflow. * If you #define NO_IEEE_Scale on a machine that uses IEEE-format * floating-point numbers and flushes underflows to zero rather * than implementing gradual underflow, then you must also #define * Sudden_Underflow. * #define USE_LOCALE to use the current locale's decimal_point value. * #define SET_INEXACT if IEEE arithmetic is being used and extra * computation should be done to set the inexact flag when the * result is inexact and avoid setting inexact when the result * is exact. In this case, dtoa.c must be compiled in * an environment, perhaps provided by #include "dtoa.c" in a * suitable wrapper, that defines two functions, * int get_inexact(void); * void clear_inexact(void); * such that get_inexact() returns a nonzero value if the * inexact bit is already set, and clear_inexact() sets the * inexact bit to 0. When SET_INEXACT is #defined, strtod * also does extra computations to set the underflow and overflow * flags when appropriate (i.e., when the result is tiny and * inexact or when it is a numeric value rounded to +-infinity). * #define NO_ERRNO if strtod should not assign errno = ERANGE when * the result overflows to +-Infinity or underflows to 0. * #define NO_HEX_FP to omit recognition of hexadecimal floating-point * values by strtod. * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) * to disable logic for "fast" testing of very long input strings * to strtod. This testing proceeds by initially truncating the * input string, then if necessary comparing the whole string with * a decimal expansion to decide close cases. This logic is only * used for input more than STRTOD_DIGLIM digits long (default 40).
*/
#ifdefined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. #endif
/* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
*/ #ifdefined(IEEE_8087) + defined(VAX) # define Storeinc(a, b, c) \
(((unsignedshort*)a)[1] = (unsignedshort)b, \
((unsignedshort*)a)[0] = (unsignedshort)c, a++) #else # define Storeinc(a, b, c) \
(((unsignedshort*)a)[0] = (unsignedshort)b, \
((unsignedshort*)a)[1] = (unsignedshort)c, a++) #endif
#ifdef RND_PRODQUOT # define rounded_product(a, b) a = rnd_prod(a, b) # define rounded_quotient(a, b) a = rnd_quot(a, b) # ifdef KR_headers externdouble rnd_prod(), rnd_quot(); # else externdouble rnd_prod(double, double), rnd_quot(double, double); # endif #else # define rounded_product(a, b) a *= b # define rounded_quotient(a, b) a /= b #endif
#ifdef NO_LONG_LONG # undef ULLong # ifdef Just_16 # undef Pack_32 /* When Pack_32 is not defined, we store 16 bits per 32-bit Long. * This makes some inner loops simpler and sometimes saves work * during multiplications, but it often seems to make things slightly * slower. Hence the default is now to store 32 bits per Long.
*/ # endif #else/* long long available */ # ifndef Llong # define Llong longlong # endif # ifndef ULLong # define ULLong unsigned Llong # endif #endif/* NO_LONG_LONG */
static Bigint* multadd #ifdef KR_headers
(b, m, a) Bigint* b; int m, a; #else
(Bigint* b, int m, int a) /* multiply by m and add a */ #endif
{ int i, wds; #ifdef ULLong
ULong* x;
ULLong carry, y; #else
ULong carry, *x, y; # ifdef Pack_32
ULong xi, z; # endif #endif
Bigint* b1;
wds = b->wds;
x = b->x;
i = 0;
carry = a; do { #ifdef ULLong
y = *x * (ULLong)m + carry;
carry = y >> 32;
*x++ = y & FFFFFFFF; #else # ifdef Pack_32
xi = *x;
y = (xi & 0xffff) * m + carry;
z = (xi >> 16) * m + (y >> 16);
carry = z >> 16;
*x++ = (z << 16) + (y & 0xffff); # else
y = *x * m + carry;
carry = y >> 16;
*x++ = y & 0xffff; # endif #endif
} while (++i < wds); if (carry) { if (wds >= b->maxwds) {
b1 = Balloc(b->k + 1);
Bcopy(b1, b);
Bfree(b);
b = b1;
}
b->x[wds++] = carry;
b->wds = wds;
} return b;
}
static Bigint* s2b #ifdef KR_headers
(s, nd0, nd, y9, dplen) CONSTchar* s; int nd0, nd, dplen;
ULong y9; #else
(constchar* s, int nd0, int nd, ULong y9, int dplen) #endif
{
Bigint* b; int i, k; Long x, y;
x = (nd + 8) / 9; for (k = 0, y = 1; x > y; y <<= 1, k++); #ifdef Pack_32
b = Balloc(k);
b->x[0] = y9;
b->wds = 1; #else
b = Balloc(k + 1);
b->x[0] = y9 & 0xffff;
b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; #endif
i = 9; if (9 < nd0) {
s += 9; do {
b = multadd(b, 10, *s++ - '0');
} while (++i < nd0);
s += dplen;
} else {
s += dplen + 9;
} for (; i < nd; i++) {
b = multadd(b, 10, *s++ - '0');
} return b;
}
staticint hi0bits #ifdef KR_headers
(x) ULong x; #else
(ULong x) #endif
{ int k = 0;
if (!(x & 0xffff0000)) {
k = 16;
x <<= 16;
} if (!(x & 0xff000000)) {
k += 8;
x <<= 8;
} if (!(x & 0xf0000000)) {
k += 4;
x <<= 4;
} if (!(x & 0xc0000000)) {
k += 2;
x <<= 2;
} if (!(x & 0x80000000)) {
k++; if (!(x & 0x40000000)) { return 32;
}
} return k;
}
staticint lo0bits #ifdef KR_headers
(y) ULong* y; #else
(ULong* y) #endif
{ int k;
ULong x = *y;
if (x & 7) { if (x & 1) { return 0;
} if (x & 2) {
*y = x >> 1; return 1;
}
*y = x >> 2; return 2;
}
k = 0; if (!(x & 0xffff)) {
k = 16;
x >>= 16;
} if (!(x & 0xff)) {
k += 8;
x >>= 8;
} if (!(x & 0xf)) {
k += 4;
x >>= 4;
} if (!(x & 0x3)) {
k += 2;
x >>= 2;
} if (!(x & 1)) {
k++;
x >>= 1; if (!x) { return 32;
}
}
*y = x; return k;
}
double strtod #ifdef KR_headers
(s00, se) CONSTchar* s00; char** se; #else
(constchar* s00, char** se) #endif
{ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; CONSTchar *s, *s0, *s1; double aadj, aadj1; Long L;
U aadj2, adj, rv, rv0;
ULong y, z;
BCinfo bc;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef Avoid_Underflow
ULong Lsb, Lsb1; #endif #ifdef SET_INEXACT int oldinexact; #endif #ifndef NO_STRTOD_BIGCOMP int req_bigcomp = 0; #endif #ifdef Honor_FLT_ROUNDS /*{*/ # ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
bc.rounding = Flt_Rounds; # else/*}{*/
bc.rounding = 1; switch (fegetround()) { case FE_TOWARDZERO:
bc.rounding = 0; break; case FE_UPWARD:
bc.rounding = 2; break; case FE_DOWNWARD:
bc.rounding = 3;
} # endif /*}}*/ #endif/*}*/ #ifdef USE_LOCALE CONSTchar* s2; #endif
sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0;
dval(&rv) = 0.; for (s = s00;; s++) switch (*s) { case'-':
sign = 1; /* no break */ case'+': if (*++s) { goto break2;
} /* no break */ case 0: goto ret0; case'\t': case'\n': case'\v': case'\f': case'\r': case' ': continue; default: goto break2;
}
break2: if (*s == '0') { #ifndef NO_HEX_FP /*{*/ switch (s[1]) { case'x': case'X': # ifdef Honor_FLT_ROUNDS
gethex(&s, &rv, bc.rounding, sign); # else
gethex(&s, &rv, 1, sign); # endif goto ret;
} #endif/*}*/
nz0 = 1; while (*++s == '0'); if (!*s) { goto ret;
}
}
s0 = s;
y = z = 0; for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) if (nd < 9) {
y = 10 * y + c - '0';
} elseif (nd < 16) {
z = 10 * z + c - '0';
}
nd0 = nd;
bc.dp0 = bc.dp1 = s - s0; for (s1 = s; s1 > s0 && *--s1 == '0';) {
++nz1;
} #ifdef USE_LOCALE
s1 = localeconv()->decimal_point; if (c == *s1) {
c = '.'; if (*++s1) {
s2 = s; for (;;) { if (*++s2 != *s1) {
c = 0; break;
} if (!*++s1) {
s = s2; break;
}
}
}
} #endif if (c == '.') {
c = *++s;
bc.dp1 = s - s0;
bc.dplen = bc.dp1 - bc.dp0; if (!nd) { for (; c == '0'; c = *++s) {
nz++;
} if (c > '0' && c <= '9') {
bc.dp0 = s0 - s;
bc.dp1 = bc.dp0 + bc.dplen;
s0 = s;
nf += nz;
nz = 0; goto have_dig;
} goto dig_done;
} for (; c >= '0' && c <= '9'; c = *++s) {
have_dig:
nz++; if (c -= '0') {
nf += nz; for (i = 1; i < nz; i++) if (nd++ < 9) {
y *= 10;
} elseif (nd <= DBL_DIG + 1) {
z *= 10;
} if (nd++ < 9) {
y = 10 * y + c;
} elseif (nd <= DBL_DIG + 1) {
z = 10 * z + c;
}
nz = nz1 = 0;
}
}
}
dig_done:
e = 0; if (c == 'e' || c == 'E') { if (!nd && !nz && !nz0) { goto ret0;
}
s00 = s;
esign = 0; switch (c = *++s) { case'-':
esign = 1; case'+':
c = *++s;
} if (c >= '0' && c <= '9') { while (c == '0') {
c = *++s;
} if (c > '0' && c <= '9') {
L = c - '0';
s1 = s; while ((c = *++s) >= '0' && c <= '9') {
L = 10 * L + c - '0';
} if (s - s1 > 8 || L > 19999) /* Avoid confusion from exponents * so large that e might overflow.
*/
{
e = 19999; /* safe for 16 bit ints */
} else {
e = (int)L;
} if (esign) {
e = -e;
}
} else {
e = 0;
}
} else {
s = s00;
}
} if (!nd) { if (!nz && !nz0) { #ifdef INFNAN_CHECK /* Check for Nan and Infinity */ if (!bc.dplen) switch (c) { case'i': case'I': if (match(&s, "nf")) {
--s; if (!match(&s, "inity")) {
++s;
}
word0(&rv) = 0x7ff00000;
word1(&rv) = 0; goto ret;
} break; case'n': case'N': if (match(&s, "an")) {
word0(&rv) = NAN_WORD0;
word1(&rv) = NAN_WORD1; # ifndef No_Hex_NaN if (*s == '(') { /*)*/
hexnan(&rv, &s);
} # endif goto ret;
}
} #endif/* INFNAN_CHECK */
ret0:
s = s00;
sign = 0;
} goto ret;
}
bc.e0 = e1 = e -= nf;
/* Now we have nd0 digits, starting at s0, followed by a * decimal point, followed by nd-nd0 digits. The number we're * after is the integer represented by those digits times
* 10**e */
if (!nd0) {
nd0 = nd;
}
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
dval(&rv) = y; if (k > 9) { #ifdef SET_INEXACT if (k > DBL_DIG) {
oldinexact = get_inexact();
} #endif
dval(&rv) = tens[k - 9] * dval(&rv) + z;
}
bd0 = 0; if (nd <= DBL_DIG #ifndef RND_PRODQUOT # ifndef Honor_FLT_ROUNDS
&& Flt_Rounds == 1 # endif #endif
) { if (!e) { goto ret;
} #ifndef ROUND_BIASED_without_Round_Up if (e > 0) { if (e <= Ten_pmax) { # ifdef VAX goto vax_ovfl_check; # else # ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) {
rv.d = -rv.d;
sign = 0;
} # endif /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; # endif
}
i = DBL_DIG - nd; if (e <= Ten_pmax + i) { /* A fancier test would sometimes let us do * this for larger i values.
*/ # ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) {
rv.d = -rv.d;
sign = 0;
} # endif
e -= i;
dval(&rv) *= tens[i]; # ifdef VAX /* VAX exponent range is so narrow we must * worry about overflow here...
*/
vax_ovfl_check:
word0(&rv) -= P * Exp_msk1; /* rv = */ rounded_product(dval(&rv), tens[e]); if ((word0(&rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) { goto ovfl;
}
word0(&rv) += P * Exp_msk1; # else /* rv = */ rounded_product(dval(&rv), tens[e]); # endif goto ret;
}
} # ifndef Inaccurate_Divide elseif (e >= -Ten_pmax) { # ifdef Honor_FLT_ROUNDS /* round correctly FLT_ROUNDS = 2 or 3 */ if (sign) {
rv.d = -rv.d;
sign = 0;
} # endif /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret;
} # endif #endif/* ROUND_BIASED_without_Round_Up */
}
e1 += nd - k;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.