/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /**************************************************************** * * 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. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 * and strtod and dtoa should round accordingly. * #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. * #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. (Unless you #define * NO_GLOBAL_STATE and call destroydtoa, 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 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_GLOBAL_STATE to avoid defining any non-const global or * static variables. Instead the necessary state is stored in an * opaque struct, DtoaState, a pointer to which must be passed to * every entry point. Two new functions are added to the API: * DtoaState *newdtoa(void); * void destroydtoa(DtoaState *);
*/
#ifdefined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 #error"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
(STATE_PARAM b, m, a) STATE_PARAM_DECL Bigint *b; int m, a; #else
(STATE_PARAM 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++ = (ULong) 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(PASS_STATE b->k+1);
Bcopy(b1, b);
Bfree(PASS_STATE b);
b = b1;
}
b->x[wds++] = (ULong) carry;
b->wds = wds;
} 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;
}
static Bigint *
i2b #ifdef KR_headers
(STATE_PARAM i) STATE_PARAM_DECL int i; #else
(STATE_PARAM int i) #endif
{
Bigint *b;
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.