/* -*- 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;
i = cmp(a,b); if (!i) {
c = Balloc(PASS_STATE 0);
c->wds = 1;
c->x[0] = 0; return c;
} if (i < 0) {
c = a;
a = b;
b = c;
i = 1;
} else
i = 0;
c = Balloc(PASS_STATE a->k);
c->sign = i;
wa = a->wds;
xa = a->x;
xae = xa + wa;
wb = b->wds;
xb = b->x;
xbe = xb + wb;
xc = c->x;
borrow = 0; #ifdef ULLong do {
y = (ULLong)*xa++ - *xb++ - borrow;
borrow = y >> 32 & (ULong)1;
*xc++ = (ULong) y & FFFFFFFF;
} while(xb < xbe); while(xa < xae) {
y = *xa++ - borrow;
borrow = y >> 32 & (ULong)1;
*xc++ = (ULong) y & FFFFFFFF;
} #else #ifdef Pack_32 do {
y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
} while(xb < xbe); while(xa < xae) {
y = (*xa & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*xa++ >> 16) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
} #else do {
y = *xa++ - *xb++ - borrow;
borrow = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
} while(xb < xbe); while(xa < xae) {
y = *xa++ - borrow;
borrow = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
} #endif #endif while(!*--xc)
wa--;
c->wds = wa; return c;
}
static Bigint *
d2b #ifdef KR_headers
(STATE_PARAM d, e, bits) STATE_PARAM_DECL U d; int *e, *bits; #else
(STATE_PARAM U d, int *e, int *bits) #endif
{
Bigint *b; int de, k;
ULong *x, y, z; #ifndef Sudden_Underflow int i; #endif #ifdef VAX
ULong d0, d1;
d0 = word0(d) >> 16 | word0(d) << 16;
d1 = word1(d) >> 16 | word1(d) << 16; #else #define d0 word0(d) #define d1 word1(d) #endif
#ifdef Pack_32
b = Balloc(PASS_STATE 1); #else
b = Balloc(PASS_STATE 2); #endif
x = b->x;
z = d0 & Frac_mask;
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ #ifdef Sudden_Underflow
de = (int)(d0 >> Exp_shift); #ifndef IBM
z |= Exp_msk11; #endif #else if ((de = (int)(d0 >> Exp_shift)))
z |= Exp_msk1; #endif #ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) {
x[0] = y | z << (32 - k);
z >>= k;
} else
x[0] = y; #ifndef Sudden_Underflow
i = #endif
b->wds = (x[1] = z) ? 2 : 1;
} else {
k = lo0bits(&z);
x[0] = z; #ifndef Sudden_Underflow
i = #endif
b->wds = 1;
k += 32;
} #else if (y = d1) { if (k = lo0bits(&y)) if (k >= 16) {
x[0] = y | z << 32 - k & 0xffff;
x[1] = z >> k - 16 & 0xffff;
x[2] = z >> k;
i = 2;
} else {
x[0] = y & 0xffff;
x[1] = y >> 16 | z << 16 - k & 0xffff;
x[2] = z >> k & 0xffff;
x[3] = z >> k+16;
i = 3;
} else {
x[0] = y & 0xffff;
x[1] = y >> 16;
x[2] = z & 0xffff;
x[3] = z >> 16;
i = 3;
}
} else { #ifdef DEBUG if (!z)
Bug("Zero passed to d2b"); #endif
k = lo0bits(&z); if (k >= 16) {
x[0] = z;
i = 0;
} else {
x[0] = z & 0xffff;
x[1] = z >> 16;
i = 1;
}
k += 32;
} while(!x[i])
--i;
b->wds = i + 1; #endif #ifndef Sudden_Underflow if (de) { #endif #ifdef IBM
*e = (de - Bias - (P-1) << 2) + k;
*bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); #else
*e = de - Bias - (P-1) + k;
*bits = P - k; #endif #ifndef Sudden_Underflow
} else {
*e = de - Bias - (P-1) + 1 + k; #ifdef Pack_32
*bits = 32*i - hi0bits(x[i-1]); #else
*bits = (i+2)*16 - hi0bits(x[i]); #endif
} #endif return b;
} #undef d0 #undef d1
Messung V0.5 in Prozent
¤ 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.0.24Bemerkung:
(vorverarbeitet am 2026-04-25)
¤
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.