Initial import of David Gay's gdtoa library for conversion between

strings and floating point.
This commit is contained in:
David Schultz 2003-03-12 20:18:32 +00:00
commit cc36ccd13b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gdtoa/dist/; revision=112158
svn path=/vendor/gdtoa/20030305/; revision=112160; tag=vendor/gdtoa/20030305
83 changed files with 24573 additions and 0 deletions

322
contrib/gdtoa/README Normal file
View File

@ -0,0 +1,322 @@
This directory contains source for a library of binary -> decimal
and decimal -> binary conversion routines, for single-, double-,
and extended-precision IEEE binary floating-point arithmetic, and
other IEEE-like binary floating-point, including "double double",
as in
T. J. Dekker, "A Floating-Point Technique for Extending the
Available Precision", Numer. Math. 18 (1971), pp. 224-242
and
"Inside Macintosh: PowerPC Numerics", Addison-Wesley, 1994
The conversion routines use double-precision floating-point arithmetic
and, where necessary, high precision integer arithmetic. The routines
are generalizations of the strtod and dtoa routines described in
David M. Gay, "Correctly Rounded Binary-Decimal and
Decimal-Binary Conversions", Numerical Analysis Manuscript
No. 90-10, Bell Labs, Murray Hill, 1990;
http://cm.bell-labs.com/cm/cs/what/ampl/REFS/rounding.ps.gz
(based in part on papers by Clinger and Steele & White: see the
references in the above paper).
The present conversion routines should be able to use any of IEEE binary,
VAX, or IBM-mainframe double-precision arithmetic internally, but I (dmg)
have so far only had a chance to test them with IEEE double precision
arithmetic.
The core conversion routines are strtodg for decimal -> binary conversions
and gdtoa for binary -> decimal conversions. These routines operate
on arrays of unsigned 32-bit integers of type ULong, a signed 32-bit
exponent of type Long, and arithmetic characteristics described in
struct FPI; FPI, Long, and ULong are defined in gdtoa.h. File arith.h
is supposed to provide #defines that cause gdtoa.h to define its
types correctly. File arithchk.c is source for a program that
generates a suitable arith.h on all systems where I've been able to
test it.
The core conversion routines are meant to be called by helper routines
that know details of the particular binary arithmetic of interest and
convert. The present directory provides helper routines for 5 variants
of IEEE binary floating-point arithmetic, each indicated by one or
two letters:
f IEEE single precision
d IEEE double precision
x IEEE extended precision, as on Intel 80x87
and software emulations of Motorola 68xxx chips
that do not pad the way the 68xxx does, but
only store 80 bits
xL IEEE extended precision, as on Motorola 68xxx chips
Q quad precision, as on Sun Sparc chips
dd double double, pairs of IEEE double numbers
whose sum is the desired value
For decimal -> binary conversions, there are three families of
helper routines: one for round-nearest:
strtof
strtod
strtodd
strtopd
strtopf
strtopx
strtopxL
strtopQ
one with rounding direction specified:
strtorf
strtord
strtordd
strtorx
strtorxL
strtorQ
and one for computing an interval (at most one bit wide) that contains
the decimal number:
strtoIf
strtoId
strtoIdd
strtoIx
strtoIxL
strtoIQ
The latter call strtoIg, which makes one call on strtodg and adjusts
the result to provide the desired interval. On systems where native
arithmetic can easily make one-ulp adjustments on values in the
desired floating-point format, it might be more efficient to use the
native arithmetic. Routine strtodI is a variant of strtoId that
illustrates one way to do this for IEEE binary double-precision
arithmetic -- but whether this is more efficient remains to be seen.
Functions strtod and strtof have "natural" return types, float and
double -- strtod is specified by the C standard, and strtof appears
in the stdlib.h of some systems, such as (at least some) Linux systems.
The other functions write their results to their final argument(s):
to the final two argument for the strtoI... (interval) functions,
and to the final argument for the others (strtop... and strtor...).
Where possible, these arguments have "natural" return types (double*
or float*), to permit at least some type checking. In reality, they
are viewed as arrays of ULong (or, for the "x" functions, UShort)
values. On systems where long double is the appropriate type, one can
pass long double* final argument(s) to these routines. The int value
that these routines return is the return value from the call they make
on strtodg; see the enum of possible return values in gdtoa.h.
Source files g_ddfmt.c, misc.c, smisc.c, strtod.c, strtodg.c, and ulp.c
should use true IEEE double arithmetic (not, e.g., double extended),
at least for storing (and viewing the bits of) the variables declared
"double" within them.
One detail indicated in struct FPI is whether the target binary
arithmetic departs from the IEEE standard by flushing denormalized
numbers to 0. On systems that do this, the helper routines for
conversion to double-double format (when compiled with
Sudden_Underflow #defined) penalize the bottom of the exponent
range so that they return a nonzero result only when the least
significant bit of the less significant member of the pair of
double values returned can be expressed as a normalized double
value. An alternative would be to drop to 53-bit precision near
the bottom of the exponent range. To get correct rounding, this
would (in general) require two calls on strtodg (one specifying
126-bit arithmetic, then, if necessary, one specifying 53-bit
arithmetic).
By default, the core routine strtodg and strtod set errno to ERANGE
if the result overflows to +Infinity or underflows to 0. Compile
these routines with NO_ERRNO #defined to inhibit errno assignments.
Routine strtod is based on netlib's "dtoa.c from fp", and
(f = strtod(s,se)) is more efficient for some conversions than, say,
strtord(s,se,1,&f). Parts of strtod require true IEEE double
arithmetic with the default rounding mode (round-to-nearest) and, on
systems with IEEE extended-precision registers, double-precision
(53-bit) rounding precision. 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.
The values returned for NaNs may be signaling NaNs on some systems,
since the rules for distinguishing signaling from quiet NaNs are
system-dependent. You can easily fix this by suitably modifying the
ULto* routines in strtor*.c.
C99's hexadecimal floating-point constants are recognized by the
strto* routines (but this feature has not yet been heavily tested).
Compiling with NO_HEX_FP #defined disables this feature.
The strto* routines do not (yet) recognize C99's NaN(...) syntax; the
strto* routines simply regard '(' as the first unprocessed input
character.
For binary -> decimal conversions, I've provided just one family
of helper routines:
g_ffmt
g_dfmt
g_ddfmt
g_xfmt
g_xLfmt
g_Qfmt
which do a "%g" style conversion either to a specified number of decimal
places (if their ndig argument is positive), or to the shortest
decimal string that rounds to the given binary floating-point value
(if ndig <= 0). They write into a buffer supplied as an argument
and return either a pointer to the end of the string (a null character)
in the buffer, if the buffer was long enough, or 0. Other forms of
conversion are easily done with the help of gdtoa(), such as %e or %f
style and conversions with direction of rounding specified (so that, if
desired, the decimal value is either >= or <= the binary value).
For an example of more general conversions based on dtoa(), see
netlib's "printf.c from ampl/solvers".
For double-double -> decimal, g_ddfmt() assumes IEEE-like arithmetic
of precision max(126, #bits(input)) bits, where #bits(input) is the
number of mantissa bits needed to represent the sum of the two double
values in the input.
The makefile creates a library, gdtoa.a. To use the helper
routines, a program only needs to include gdtoa.h. All the
source files for gdtoa.a include a more extensive gdtoaimp.h;
among other things, gdtoaimp.h has #defines that make "internal"
names end in _D2A. To make a "system" library, one could modify
these #defines to make the names start with __.
Various comments about possible #defines appear in gdtoaimp.h,
but for most purposes, arith.h should set suitable #defines.
Systems with preemptive scheduling of multiple threads require some
manual intervention. On such systems, it's necessary to compile
dmisc.c, dtoa.c gdota.c, and misc.c with MULTIPLE_THREADS #defined,
and to 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.)
Routines that call dtoa or gdtoa directly must also invoke freedtoa(s)
to free the value s returned by dtoa or gdtoa. It's OK to do so whether
or not MULTIPLE_THREADS is #defined, and the helper g_*fmt routines
listed above all do this indirectly (in gfmt_D2A(), which they all call).
By default, there is a private pool of memory of length 2000 bytes
for intermediate quantities, and MALLOC (see gdtoaimp.h) is called only
if the private pool does not suffice. 2000 is large enough that MALLOC
is called only under very unusual circumstances (decimal -> binary
conversion of very long strings) for conversions to and from double
precision. For systems with preemptivaly scheduled multiple threads
or for conversions to extended or quad, it may be appropriate to
#define PRIVATE_MEM nnnn, where nnnn is a suitable value > 2000.
For extended and quad precisions, -DPRIVATE_MEM=20000 is probably
plenty even for many digits at the ends of the exponent range.
Use of the private pool avoids some overhead.
Directory test provides some test routines. See its README.
I've also tested this stuff (except double double conversions)
with Vern Paxson's testbase program: see
V. Paxson and W. Kahan, "A Program for Testing IEEE Binary-Decimal
Conversion", manuscript, May 1991,
ftp://ftp.ee.lbl.gov/testbase-report.ps.Z .
(The same ftp directory has source for testbase.)
Some system-dependent additions to CFLAGS in the makefile:
HU-UX: -Aa -Ae
OSF (DEC Unix): -ieee_with_no_inexact
SunOS 4.1x: -DKR_headers -DBad_float_h
If you want to put this stuff into a shared library and your
operating system requires export lists for shared libraries,
the following would be an appropriate export list:
dtoa
freedtoa
g_Qfmt
g_ddfmt
g_dfmt
g_ffmt
g_xLfmt
g_xfmt
gdtoa
strtoIQ
strtoId
strtoIdd
strtoIf
strtoIx
strtoIxL
strtod
strtodI
strtodg
strtof
strtopQ
strtopd
strtopdd
strtopf
strtopx
strtopxL
strtorQ
strtord
strtordd
strtorf
strtorx
strtorxL
When time permits, I (dmg) hope to write in more detail about the
present conversion routines; for now, this README file must suffice.
Meanwhile, if you wish to write helper functions for other kinds of
IEEE-like arithmetic, some explanation of struct FPI and the bits
array may be helpful. Both gdtoa and strtodg operate on a bits array
described by FPI *fpi. The bits array is of type ULong, a 32-bit
unsigned integer type. Floating-point numbers have fpi->nbits bits,
with the least significant 32 bits in bits[0], the next 32 bits in
bits[1], etc. These numbers are regarded as integers multiplied by
2^e (i.e., 2 to the power of the exponent e), where e is the second
argument (be) to gdtoa and is stored in *exp by strtodg. The minimum
and maximum exponent values fpi->emin and fpi->emax for normalized
floating-point numbers reflect this arrangement. For example, the
P754 standard for binary IEEE arithmetic specifies doubles as having
53 bits, with normalized values of the form 1.xxxxx... times 2^(b-1023),
with 52 bits (the x's) and the biased exponent b represented explicitly;
b is an unsigned integer in the range 1 <= b <= 2046 for normalized
finite doubles, b = 0 for denormals, and b = 2047 for Infinities and NaNs.
To turn an IEEE double into the representation used by strtodg and gdtoa,
we multiply 1.xxxx... by 2^52 (to make it an integer) and reduce the
exponent e = (b-1023) by 52:
fpi->emin = 1 - 1023 - 52
fpi->emax = 1046 - 1023 - 52
In various wrappers for IEEE double, we actually write -53 + 1 rather
than -52, to emphasize that there are 53 bits including one implicit bit.
Field fpi->rounding indicates the desired rounding direction, with
possible values
FPI_Round_zero = toward 0,
FPI_Round_near = unbiased rounding -- the IEEE default,
FPI_Round_up = toward +Infinity, and
FPI_Round_down = toward -Infinity
given in gdtoa.h.
Field fpi->sudden_underflow indicates whether strtodg should return
denormals or flush them to zero. Normal floating-point numbers have
bit fpi->nbits in the bits array on. Denormals have it off, with
exponent = fpi->emin. Strtodg provides distinct return values for normals
and denormals; see gdtoa.h.
Please send comments to
David M. Gay
Bell Labs, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636, U.S.A.
dmg@research.bell-labs.com

182
contrib/gdtoa/arithchk.c Normal file
View File

@ -0,0 +1,182 @@
/****************************************************************
Copyright (C) 1997, 1998 Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Try to deduce arith.h from arithmetic properties. */
#include <stdio.h>
static int dalign;
typedef struct
Akind {
char *name;
int kind;
} Akind;
static Akind
IEEE_8087 = { "IEEE_8087", 1 },
IEEE_MC68k = { "IEEE_MC68k", 2 },
IBM = { "IBM", 3 },
VAX = { "VAX", 4 },
CRAY = { "CRAY", 5};
static Akind *
Lcheck()
{
union {
double d;
long L[2];
} u;
struct {
double d;
long L;
} x[2];
if (sizeof(x) > 2*(sizeof(double) + sizeof(long)))
dalign = 1;
u.L[0] = u.L[1] = 0;
u.d = 1e13;
if (u.L[0] == 1117925532 && u.L[1] == -448790528)
return &IEEE_MC68k;
if (u.L[1] == 1117925532 && u.L[0] == -448790528)
return &IEEE_8087;
if (u.L[0] == -2065213935 && u.L[1] == 10752)
return &VAX;
if (u.L[0] == 1267827943 && u.L[1] == 704643072)
return &IBM;
return 0;
}
static Akind *
icheck()
{
union {
double d;
int L[2];
} u;
struct {
double d;
int L;
} x[2];
if (sizeof(x) > 2*(sizeof(double) + sizeof(int)))
dalign = 1;
u.L[0] = u.L[1] = 0;
u.d = 1e13;
if (u.L[0] == 1117925532 && u.L[1] == -448790528)
return &IEEE_MC68k;
if (u.L[1] == 1117925532 && u.L[0] == -448790528)
return &IEEE_8087;
if (u.L[0] == -2065213935 && u.L[1] == 10752)
return &VAX;
if (u.L[0] == 1267827943 && u.L[1] == 704643072)
return &IBM;
return 0;
}
char *emptyfmt = ""; /* avoid possible warning message with printf("") */
static Akind *
ccheck()
{
union {
double d;
long L;
} u;
long Cray1;
/* Cray1 = 4617762693716115456 -- without overflow on non-Crays */
Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762;
if (printf(emptyfmt, Cray1) >= 0)
Cray1 = 1000000*Cray1 + 693716;
if (printf(emptyfmt, Cray1) >= 0)
Cray1 = 1000000*Cray1 + 115456;
u.d = 1e13;
if (u.L == Cray1)
return &CRAY;
return 0;
}
static int
fzcheck()
{
double a, b;
int i;
a = 1.;
b = .1;
for(i = 155;; b *= b, i >>= 1) {
if (i & 1) {
a *= b;
if (i == 1)
break;
}
}
b = a * a;
return b == 0.;
}
main()
{
Akind *a = 0;
int Ldef = 0;
FILE *f;
#ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */
f = fopen("arith.h", "w");
if (!f) {
printf("Cannot open arith.h\n");
return 1;
}
#else
f = stdout;
#endif
if (sizeof(double) == 2*sizeof(long))
a = Lcheck();
else if (sizeof(double) == 2*sizeof(int)) {
Ldef = 1;
a = icheck();
}
else if (sizeof(double) == sizeof(long))
a = ccheck();
if (a) {
fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n",
a->name, a->kind);
if (Ldef)
fprintf(f, "#define Long int\n#define Intcast (int)(long)\n");
if (dalign)
fprintf(f, "#define Double_Align\n");
if (sizeof(char*) == 8)
fprintf(f, "#define X64_bit_pointers\n");
#ifndef NO_LONG_LONG
if (sizeof(long long) < 8)
#endif
fprintf(f, "#define NO_LONG_LONG\n");
if (a->kind <= 2 && fzcheck())
fprintf(f, "#define Sudden_Underflow\n");
return 0;
}
fprintf(f, "/* Unknown arithmetic */\n");
return 1;
}

222
contrib/gdtoa/dmisc.c Normal file
View File

@ -0,0 +1,222 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#ifndef MULTIPLE_THREADS
char *dtoa_result;
#endif
char *
#ifdef KR_headers
rv_alloc(i) int i;
#else
rv_alloc(int i)
#endif
{
int j, k, *r;
j = sizeof(ULong);
for(k = 0;
sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
j <<= 1)
k++;
r = (int*)Balloc(k);
*r = k;
return
#ifndef MULTIPLE_THREADS
dtoa_result =
#endif
(char *)(r+1);
}
char *
#ifdef KR_headers
nrv_alloc(s, rve, n) char *s, **rve; int n;
#else
nrv_alloc(char *s, char **rve, int n)
#endif
{
char *rv, *t;
t = rv = rv_alloc(n);
while((*t = *s++) !=0)
t++;
if (rve)
*rve = t;
return rv;
}
/* freedtoa(s) must be used to free values s returned by dtoa
* when MULTIPLE_THREADS is #defined. It should be used in all cases,
* but for consistency with earlier versions of dtoa, it is optional
* when MULTIPLE_THREADS is not defined.
*/
void
#ifdef KR_headers
freedtoa(s) char *s;
#else
freedtoa(char *s)
#endif
{
Bigint *b = (Bigint *)((int *)s - 1);
b->maxwds = 1 << (b->k = *(int*)b);
Bfree(b);
#ifndef MULTIPLE_THREADS
if (s == dtoa_result)
dtoa_result = 0;
#endif
}
int
quorem
#ifdef KR_headers
(b, S) Bigint *b, *S;
#else
(Bigint *b, Bigint *S)
#endif
{
int n;
ULong *bx, *bxe, q, *sx, *sxe;
#ifdef ULLong
ULLong borrow, carry, y, ys;
#else
ULong borrow, carry, y, ys;
#ifdef Pack_32
ULong si, z, zs;
#endif
#endif
n = S->wds;
#ifdef DEBUG
/*debug*/ if (b->wds > n)
/*debug*/ Bug("oversize b in quorem");
#endif
if (b->wds < n)
return 0;
sx = S->x;
sxe = sx + --n;
bx = b->x;
bxe = bx + n;
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
#ifdef DEBUG
/*debug*/ if (q > 9)
/*debug*/ Bug("oversized quotient in quorem");
#endif
if (q) {
borrow = 0;
carry = 0;
do {
#ifdef ULLong
ys = *sx++ * (ULLong)q + carry;
carry = ys >> 32;
y = *bx - (ys & 0xffffffffUL) - borrow;
borrow = y >> 32 & 1UL;
*bx++ = y & 0xffffffffUL;
#else
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) * q + carry;
zs = (si >> 16) * q + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*bx >> 16) - (zs & 0xffff) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(bx, z, y);
#else
ys = *sx++ * q + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
*bx++ = y & 0xffff;
#endif
#endif
}
while(sx <= sxe);
if (!*bxe) {
bx = b->x;
while(--bxe > bx && !*bxe)
--n;
b->wds = n;
}
}
if (cmp(b, S) >= 0) {
q++;
borrow = 0;
carry = 0;
bx = b->x;
sx = S->x;
do {
#ifdef ULLong
ys = *sx++ + carry;
carry = ys >> 32;
y = *bx - (ys & 0xffffffffUL) - borrow;
borrow = y >> 32 & 1UL;
*bx++ = y & 0xffffffffUL;
#else
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
z = (*bx >> 16) - (zs & 0xffff) - borrow;
borrow = (z & 0x10000) >> 16;
Storeinc(bx, z, y);
#else
ys = *sx++ + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) - borrow;
borrow = (y & 0x10000) >> 16;
*bx++ = y & 0xffff;
#endif
#endif
}
while(sx <= sxe);
bx = b->x;
bxe = bx + n;
if (!*bxe) {
while(--bxe > bx && !*bxe)
--n;
b->wds = n;
}
}
return q;
}

759
contrib/gdtoa/dtoa.c Normal file
View File

@ -0,0 +1,759 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
* 1. Rather than iterating, we use a simple numeric overestimate
* to determine k = floor(log10(d)). We scale relevant
* quantities using O(log2(k)) rather than O(k) multiplications.
* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
* try to generate digits strictly left to right. Instead, we
* compute with fewer bits and propagate the carry if necessary
* when rounding the final digit up. This is often faster.
* 3. Under the assumption that input will be rounded nearest,
* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
* That is, we allow equality in stopping tests when the
* round-nearest rule will give the same floating-point value
* as would satisfaction of the stopping test with strict
* inequality.
* 4. We remove common factors of powers of 2 from relevant
* quantities.
* 5. When converting floating-point integers less than 1e16,
* we use floating-point arithmetic rather than resorting
* to multiple-precision integers.
* 6. When asked to produce fewer than 15 digits, we first try
* to get by with floating-point arithmetic; we resort to
* multiple-precision integer arithmetic only if we cannot
* guarantee that the floating-point calculation has given
* the correctly rounded result. For k requested digits and
* "uniformly" distributed input, the probability is
* something like 10^(k-15) that we must resort to the Long
* calculation.
*/
#ifdef Honor_FLT_ROUNDS
#define Rounding rounding
#undef Check_FLT_ROUNDS
#define Check_FLT_ROUNDS
#else
#define Rounding Flt_Rounds
#endif
char *
dtoa
#ifdef KR_headers
(d, mode, ndigits, decpt, sign, rve)
double d; int mode, ndigits, *decpt, *sign; char **rve;
#else
(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
#endif
{
/* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from
the returned string. If not null, *rve is set to point
to the end of the return value. If d is +-Infinity or NaN,
then *decpt is set to 9999.
mode:
0 ==> shortest string that yields d when read in
and rounded to nearest.
1 ==> like 0, but with Steele & White stopping rule;
e.g. with IEEE P754 arithmetic , mode 0 gives
1e23 whereas mode 1 gives 9.999999999999999e22.
2 ==> max(1,ndigits) significant digits. This gives a
return value similar to that of ecvt, except
that trailing zeros are suppressed.
3 ==> through ndigits past the decimal point. This
gives a return value similar to that from fcvt,
except that trailing zeros are suppressed, and
ndigits can be negative.
4,5 ==> similar to 2 and 3, respectively, but (in
round-nearest mode) with the tests of mode 0 to
possibly return a shorter string that rounds to d.
With IEEE arithmetic and compilation with
-DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
as modes 2 and 3 when FLT_ROUNDS != 1.
6-9 ==> Debugging modes similar to mode - 4: don't try
fast floating-point estimate (if applicable).
Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value
to hold the suppressed trailing zeros.
*/
int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
spec_case, try_quick;
Long L;
#ifndef Sudden_Underflow
int denorm;
ULong x;
#endif
Bigint *b, *b1, *delta, *mlo, *mhi, *S;
double d2, ds, eps;
char *s, *s0;
#ifdef Honor_FLT_ROUNDS
int rounding;
#endif
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
#ifndef MULTIPLE_THREADS
if (dtoa_result) {
freedtoa(dtoa_result);
dtoa_result = 0;
}
#endif
if (word0(d) & Sign_bit) {
/* set sign for everything, including 0's and NaNs */
*sign = 1;
word0(d) &= ~Sign_bit; /* clear sign bit */
}
else
*sign = 0;
#if defined(IEEE_Arith) + defined(VAX)
#ifdef IEEE_Arith
if ((word0(d) & Exp_mask) == Exp_mask)
#else
if (word0(d) == 0x8000)
#endif
{
/* Infinity or NaN */
*decpt = 9999;
#ifdef IEEE_Arith
if (!word1(d) && !(word0(d) & 0xfffff))
return nrv_alloc("Infinity", rve, 8);
#endif
return nrv_alloc("NaN", rve, 3);
}
#endif
#ifdef IBM
dval(d) += 0; /* normalize */
#endif
if (!dval(d)) {
*decpt = 1;
return nrv_alloc("0", rve, 1);
}
#ifdef SET_INEXACT
try_quick = oldinexact = get_inexact();
inexact = 1;
#endif
#ifdef Honor_FLT_ROUNDS
if ((rounding = Flt_Rounds) >= 2) {
if (*sign)
rounding = rounding == 2 ? 0 : 2;
else
if (rounding != 2)
rounding = 0;
}
#endif
b = d2b(dval(d), &be, &bbits);
#ifdef Sudden_Underflow
i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
#else
if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
#endif
dval(d2) = dval(d);
word0(d2) &= Frac_mask1;
word0(d2) |= Exp_11;
#ifdef IBM
if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0)
dval(d2) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
* log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
*
* This suggests computing an approximation k to log10(d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
*
* We want k to be too large rather than too small.
* The error in the first-order Taylor series approximation
* is in our favor, so we just round up the constant enough
* to compensate for any error in the multiplication of
* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
* adding 1e-13 to the constant term more than suffices.
* Hence we adjust the constant term to 0.1760912590558.
* (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.)
*/
i -= Bias;
#ifdef IBM
i <<= 2;
i += j;
#endif
#ifndef Sudden_Underflow
denorm = 0;
}
else {
/* d is denormalized */
i = bbits + be + (Bias + (P-1) - 1);
x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32
: word1(d) << 32 - i;
dval(d2) = x;
word0(d2) -= 31*Exp_msk1; /* adjust exponent */
i -= (Bias + (P-1) - 1) + 1;
denorm = 1;
}
#endif
ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
k = (int)ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */
k_check = 1;
if (k >= 0 && k <= Ten_pmax) {
if (dval(d) < tens[k])
k--;
k_check = 0;
}
j = bbits - i - 1;
if (j >= 0) {
b2 = 0;
s2 = j;
}
else {
b2 = -j;
s2 = 0;
}
if (k >= 0) {
b5 = 0;
s5 = k;
s2 += k;
}
else {
b2 -= k;
b5 = -k;
s5 = 0;
}
if (mode < 0 || mode > 9)
mode = 0;
#ifndef SET_INEXACT
#ifdef Check_FLT_ROUNDS
try_quick = Rounding == 1;
#else
try_quick = 1;
#endif
#endif /*SET_INEXACT*/
if (mode > 5) {
mode -= 4;
try_quick = 0;
}
leftright = 1;
switch(mode) {
case 0:
case 1:
ilim = ilim1 = -1;
i = 18;
ndigits = 0;
break;
case 2:
leftright = 0;
/* no break */
case 4:
if (ndigits <= 0)
ndigits = 1;
ilim = ilim1 = i = ndigits;
break;
case 3:
leftright = 0;
/* no break */
case 5:
i = ndigits + k + 1;
ilim = i;
ilim1 = i - 1;
if (i <= 0)
i = 1;
}
s = s0 = rv_alloc(i);
#ifdef Honor_FLT_ROUNDS
if (mode > 1 && rounding != 1)
leftright = 0;
#endif
if (ilim >= 0 && ilim <= Quick_max && try_quick) {
/* Try to get by with floating-point arithmetic. */
i = 0;
dval(d2) = dval(d);
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
if (k > 0) {
ds = tens[k&0xf];
j = k >> 4;
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
dval(d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
if (j & 1) {
ieps++;
ds *= bigtens[i];
}
dval(d) /= ds;
}
else if (( j1 = -k )!=0) {
dval(d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
dval(d) *= bigtens[i];
}
}
if (k_check && dval(d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
dval(d) *= 10.;
ieps++;
}
dval(eps) = ieps*dval(d) + 7.;
word0(eps) -= (P-1)*Exp_msk1;
if (ilim == 0) {
S = mhi = 0;
dval(d) -= 5.;
if (dval(d) > dval(eps))
goto one_digit;
if (dval(d) < -dval(eps))
goto no_digits;
goto fast_failed;
}
#ifndef No_leftright
if (leftright) {
/* Use Steele & White method of only
* generating digits needed.
*/
dval(eps) = 0.5/tens[ilim-1] - dval(eps);
for(i = 0;;) {
L = dval(d);
dval(d) -= L;
*s++ = '0' + (int)L;
if (dval(d) < dval(eps))
goto ret1;
if (1. - dval(d) < dval(eps))
goto bump_up;
if (++i >= ilim)
break;
dval(eps) *= 10.;
dval(d) *= 10.;
}
}
else {
#endif
/* Generate ilim digits, then fix them up. */
dval(eps) *= tens[ilim-1];
for(i = 1;; i++, dval(d) *= 10.) {
L = (Long)(dval(d));
if (!(dval(d) -= L))
ilim = i;
*s++ = '0' + (int)L;
if (i == ilim) {
if (dval(d) > 0.5 + dval(eps))
goto bump_up;
else if (dval(d) < 0.5 - dval(eps)) {
while(*--s == '0');
s++;
goto ret1;
}
break;
}
}
#ifndef No_leftright
}
#endif
fast_failed:
s = s0;
dval(d) = dval(d2);
k = k0;
ilim = ilim0;
}
/* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max) {
/* Yes. */
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
if (ilim < 0 || dval(d) <= 5*ds)
goto no_digits;
goto one_digit;
}
for(i = 1;; i++, dval(d) *= 10.) {
L = (Long)(dval(d) / ds);
dval(d) -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (dval(d) < 0) {
L--;
dval(d) += ds;
}
#endif
*s++ = '0' + (int)L;
if (!dval(d)) {
#ifdef SET_INEXACT
inexact = 0;
#endif
break;
}
if (i == ilim) {
#ifdef Honor_FLT_ROUNDS
if (mode > 1)
switch(rounding) {
case 0: goto ret1;
case 2: goto bump_up;
}
#endif
dval(d) += dval(d);
if (dval(d) > ds || dval(d) == ds && L & 1) {
bump_up:
while(*--s == '9')
if (s == s0) {
k++;
*s = '0';
break;
}
++*s++;
}
break;
}
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright) {
i =
#ifndef Sudden_Underflow
denorm ? be + (Bias + (P-1) - 1 + 1) :
#endif
#ifdef IBM
1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
#else
1 + P - bbits;
#endif
b2 += i;
s2 += i;
mhi = i2b(1);
}
if (m2 > 0 && s2 > 0) {
i = m2 < s2 ? m2 : s2;
b2 -= i;
m2 -= i;
s2 -= i;
}
if (b5 > 0) {
if (leftright) {
if (m5 > 0) {
mhi = pow5mult(mhi, m5);
b1 = mult(mhi, b);
Bfree(b);
b = b1;
}
if (( j = b5 - m5 )!=0)
b = pow5mult(b, j);
}
else
b = pow5mult(b, b5);
}
S = i2b(1);
if (s5 > 0)
S = pow5mult(S, s5);
/* Check for special case that d is a normalized power of 2. */
spec_case = 0;
if ((mode < 2 || leftright)
#ifdef Honor_FLT_ROUNDS
&& rounding == 1
#endif
) {
if (!word1(d) && !(word0(d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0(d) & (Exp_mask & ~Exp_msk1)
#endif
) {
/* The special case */
b2 += Log2P;
s2 += Log2P;
spec_case = 1;
}
}
/* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits.
*
* Perhaps we should just compute leading 28 bits of S once
* and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q.
*/
#ifdef Pack_32
if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0)
i = 32 - i;
#else
if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0)
i = 16 - i;
#endif
if (i > 4) {
i -= 4;
b2 += i;
m2 += i;
s2 += i;
}
else if (i < 4) {
i += 28;
b2 += i;
m2 += i;
s2 += i;
}
if (b2 > 0)
b = lshift(b, b2);
if (s2 > 0)
S = lshift(S, s2);
if (k_check) {
if (cmp(b,S) < 0) {
k--;
b = multadd(b, 10, 0); /* we botched the k estimate */
if (leftright)
mhi = multadd(mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && (mode == 3 || mode == 5)) {
if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
/* no digits, fcvt style */
no_digits:
k = -1 - ndigits;
goto ret;
}
one_digit:
*s++ = '1';
k++;
goto ret;
}
if (leftright) {
if (m2 > 0)
mhi = lshift(mhi, m2);
/* Compute mlo -- check for special case
* that d is a normalized power of 2.
*/
mlo = mhi;
if (spec_case) {
mhi = Balloc(mhi->k);
Bcopy(mhi, mlo);
mhi = lshift(mhi, Log2P);
}
for(i = 1;;i++) {
dig = quorem(b,S) + '0';
/* Do we yet have the shortest decimal string
* that will round to d?
*/
j = cmp(b, mlo);
delta = diff(S, mhi);
j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(delta);
#ifndef ROUND_BIASED
if (j1 == 0 && mode != 1 && !(word1(d) & 1)
#ifdef Honor_FLT_ROUNDS
&& rounding >= 1
#endif
) {
if (dig == '9')
goto round_9_up;
if (j > 0)
dig++;
#ifdef SET_INEXACT
else if (!b->x[0] && b->wds <= 1)
inexact = 0;
#endif
*s++ = dig;
goto ret;
}
#endif
if (j < 0 || j == 0 && mode != 1
#ifndef ROUND_BIASED
&& !(word1(d) & 1)
#endif
) {
if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif
goto accept_dig;
}
#ifdef Honor_FLT_ROUNDS
if (mode > 1)
switch(rounding) {
case 0: goto accept_dig;
case 2: goto keep_dig;
}
#endif /*Honor_FLT_ROUNDS*/
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
if ((j1 > 0 || j1 == 0 && dig & 1)
&& dig++ == '9')
goto round_9_up;
}
accept_dig:
*s++ = dig;
goto ret;
}
if (j1 > 0) {
#ifdef Honor_FLT_ROUNDS
if (!rounding)
goto accept_dig;
#endif
if (dig == '9') { /* possible if i == 1 */
round_9_up:
*s++ = '9';
goto roundoff;
}
*s++ = dig + 1;
goto ret;
}
#ifdef Honor_FLT_ROUNDS
keep_dig:
#endif
*s++ = dig;
if (i == ilim)
break;
b = multadd(b, 10, 0);
if (mlo == mhi)
mlo = mhi = multadd(mhi, 10, 0);
else {
mlo = multadd(mlo, 10, 0);
mhi = multadd(mhi, 10, 0);
}
}
}
else
for(i = 1;; i++) {
*s++ = dig = quorem(b,S) + '0';
if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
#endif
goto ret;
}
if (i >= ilim)
break;
b = multadd(b, 10, 0);
}
/* Round off last digit */
#ifdef Honor_FLT_ROUNDS
switch(rounding) {
case 0: goto trimzeros;
case 2: goto roundoff;
}
#endif
b = lshift(b, 1);
j = cmp(b, S);
if (j > 0 || j == 0 && dig & 1) {
roundoff:
while(*--s == '9')
if (s == s0) {
k++;
*s++ = '1';
goto ret;
}
++*s++;
}
else {
trimzeros:
while(*--s == '0');
s++;
}
ret:
Bfree(S);
if (mhi) {
if (mlo && mlo != mhi)
Bfree(mlo);
Bfree(mhi);
}
ret1:
#ifdef SET_INEXACT
if (inexact) {
if (!oldinexact) {
word0(d) = Exp_1 + (70 << Exp_shift);
word1(d) = 0;
dval(d) += 1.;
}
}
else if (!oldinexact)
clear_inexact();
#endif
Bfree(b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
return s0;
}

120
contrib/gdtoa/g_Qfmt.c Normal file
View File

@ -0,0 +1,120 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
char*
#ifdef KR_headers
g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
#else
g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize)
#endif
{
static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[4], *L, sign;
int decpt, ex, i, mode;
if (ndig < 0)
ndig = 0;
if (bufsize < ndig + 10)
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[3] = L[_0] & 0xffff;
bits[2] = L[_1];
bits[1] = L[_2];
bits[0] = L[_3];
b = buf;
if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (bits[0] | bits[1] | bits[2] | bits[3])
b = strcpy(b, "NaN");
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, "Infinity");
}
return b;
}
i = STRTOG_Normal;
bits[3] |= 0x10000;
}
else if (bits[0] | bits[1] | bits[2] | bits[3]) {
i = STRTOG_Denormal;
ex = 1;
}
else {
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 112;
mode = 2;
if (ndig <= 0) {
if (bufsize < 48)
return 0;
mode = 0;
}
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign);
}

97
contrib/gdtoa/g__fmt.c Normal file
View File

@ -0,0 +1,97 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
char *
#ifdef KR_headers
g__fmt(b, s, se, decpt, sign) char *b; char *s; char *se; int decpt; ULong sign;
#else
g__fmt(char *b, char *s, char *se, int decpt, ULong sign)
#endif
{
int i, j, k;
char *s0 = s;
if (sign)
*b++ = '-';
if (decpt <= -4 || decpt > se - s + 5) {
*b++ = *s++;
if (*s) {
*b++ = '.';
while((*b = *s++) !=0)
b++;
}
*b++ = 'e';
/* sprintf(b, "%+.2d", decpt - 1); */
if (--decpt < 0) {
*b++ = '-';
decpt = -decpt;
}
else
*b++ = '+';
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}
for(;;) {
i = decpt / k;
*b++ = i + '0';
if (--j <= 0)
break;
decpt -= i*k;
decpt *= 10;
}
*b = 0;
}
else if (decpt <= 0) {
*b++ = '.';
for(; decpt < 0; decpt++)
*b++ = '0';
while((*b = *s++) !=0)
b++;
}
else {
while((*b = *s++) !=0) {
b++;
if (--decpt == 0 && *s)
*b++ = '.';
}
for(; decpt > 0; decpt--)
*b++ = '0';
*b = 0;
}
freedtoa(s0);
return b;
}

161
contrib/gdtoa/g_ddfmt.c Normal file
View File

@ -0,0 +1,161 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#include <string.h>
char *
#ifdef KR_headers
g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize;
#else
g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize)
#endif
{
FPI fpi;
char *b, *s, *se;
ULong *L, bits0[4], *bits, *zx;
int bx, by, decpt, ex, ey, i, j, mode;
Bigint *x, *y, *z;
double ddx[2];
if (bufsize < 10 || bufsize < ndig + 8)
return 0;
L = (ULong*)dd;
if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) {
/* Infinity or NaN */
if (L[_0] & 0xfffff || L[_1]) {
nanret:
return strcp(buf, "NaN");
}
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
if (L[2+_0] & 0xfffff || L[2+_1])
goto nanret;
if ((L[_0] ^ L[2+_0]) & 0x80000000L)
goto nanret; /* Infinity - Infinity */
}
infret:
b = buf;
if (L[_0] & 0x80000000L)
*b++ = '-';
return strcp(b, "Infinity");
}
if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
L += 2;
if (L[_0] & 0xfffff || L[_1])
goto nanret;
goto infret;
}
if (dd[0] + dd[1] == 0.) {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[_0] & L[2+_0] & 0x80000000L)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) {
ddx[1] = dd[0];
ddx[0] = dd[1];
dd = ddx;
L = (ULong*)dd;
}
z = d2b(dd[0], &ex, &bx);
if (dd[1] == 0.)
goto no_y;
x = z;
y = d2b(dd[1], &ey, &by);
if ( (i = ex - ey) !=0) {
if (i > 0) {
x = lshift(x, i);
ex = ey;
}
else
y = lshift(y, -i);
}
if ((L[_0] ^ L[2+_0]) & 0x80000000L) {
z = diff(x, y);
if (L[_0] & 0x80000000L)
z->sign = 1 - z->sign;
}
else {
z = sum(x, y);
if (L[_0] & 0x80000000L)
z->sign = 1;
}
Bfree(x);
Bfree(y);
no_y:
bits = zx = z->x;
for(i = 0; !*zx; zx++)
i += 32;
i += lo0bits(zx);
if (i) {
rshift(z, i);
ex += i;
}
fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
if (fpi.nbits < 106) {
fpi.nbits = 106;
if (j < 3) {
for(i = 0; i <= j; i++)
bits0[i] = bits[i];
while(i < 4)
bits0[i++] = 0;
bits = bits0;
}
}
mode = 2;
if (ndig <= 0) {
if (bufsize < (int)(fpi.nbits * .301029995664) + 10) {
Bfree(z);
return 0;
}
mode = 0;
}
fpi.emin = 1-1023-53+1;
fpi.emax = 2046-1023-106+1;
fpi.rounding = FPI_Round_near;
fpi.sudden_underflow = 0;
i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
b = g__fmt(buf, s, se, decpt, z->sign);
Bfree(z);
return b;
}

95
contrib/gdtoa/g_dfmt.c Normal file
View File

@ -0,0 +1,95 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
char*
#ifdef KR_headers
g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize;
#else
g_dfmt(char *buf, double *d, int ndig, unsigned bufsize)
#endif
{
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
if (ndig < 0)
ndig = 0;
if (bufsize < ndig + 10)
return 0;
L = (ULong*)d;
sign = L[_0] & 0x80000000L;
if ((L[_0] & 0x7ff00000) == 0x7ff00000) {
/* Infinity or NaN */
if (L[_0] & 0xfffff || L[_1]) {
return strcp(buf, "NaN");
}
b = buf;
if (sign)
*b++ = '-';
return strcp(b, "Infinity");
}
if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[_0] & 0x80000000L)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
bits[0] = L[_1];
bits[1] = L[_0] & 0xfffff;
if ( (ex = (L[_0] >> 20) & 0x7ff) !=0)
bits[1] |= 0x100000;
else
ex = 1;
ex -= 0x3ff + 52;
mode = 2;
if (ndig <= 0) {
if (bufsize < 25)
return 0;
mode = 0;
}
i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign);
}

94
contrib/gdtoa/g_ffmt.c Normal file
View File

@ -0,0 +1,94 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
char*
#ifdef KR_headers
g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize;
#else
g_ffmt(char *buf, float *f, int ndig, unsigned bufsize)
#endif
{
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
char *b, *s, *se;
ULong bits[1], *L, sign;
int decpt, ex, i, mode;
if (ndig < 0)
ndig = 0;
if (bufsize < ndig + 10)
return 0;
L = (ULong*)f;
sign = L[0] & 0x80000000L;
if ((L[0] & 0x7f800000) == 0x7f800000) {
/* Infinity or NaN */
if (L[0] & 0x7fffff) {
return strcp(buf, "NaN");
}
b = buf;
if (sign)
*b++ = '-';
return strcp(b, "Infinity");
}
if (*f == 0.) {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[0] & 0x80000000L)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
bits[0] = L[0] & 0x7fffff;
if ( (ex = (L[0] >> 23) & 0xff) !=0)
bits[0] |= 0x800000;
else
ex = 1;
ex -= 0x7f + 23;
mode = 2;
if (ndig <= 0) {
if (bufsize < 16)
return 0;
mode = 0;
}
i = STRTOG_Normal;
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign);
}

114
contrib/gdtoa/g_xLfmt.c Normal file
View File

@ -0,0 +1,114 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
char*
#ifdef KR_headers
g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
#else
g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize)
#endif
{
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[2], *L, sign;
int decpt, ex, i, mode;
if (ndig < 0)
ndig = 0;
if (bufsize < ndig + 10)
return 0;
L = (ULong*)V;
sign = L[_0] & 0x80000000L;
bits[1] = L[_1];
bits[0] = L[_2];
if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (bits[0] | bits[1])
b = strcp(buf, "NaN");
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, "Infinity");
}
return b;
}
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) {
i = STRTOG_Denormal;
}
else {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 63;
mode = 2;
if (ndig <= 0) {
if (bufsize < 32)
return 0;
mode = 0;
}
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign);
}

119
contrib/gdtoa/g_xfmt.c Normal file
View File

@ -0,0 +1,119 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
char*
#ifdef KR_headers
g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize;
#else
g_xfmt(char *buf, void *V, int ndig, unsigned bufsize)
#endif
{
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
char *b, *s, *se;
ULong bits[2], sign;
UShort *L;
int decpt, ex, i, mode;
if (ndig < 0)
ndig = 0;
if (bufsize < ndig + 10)
return 0;
L = (UShort *)V;
sign = L[_0] & 0x8000;
bits[1] = (L[_1] << 16) | L[_2];
bits[0] = (L[_3] << 16) | L[_4];
if ( (ex = L[_0] & 0x7fff) !=0) {
if (ex == 0x7fff) {
/* Infinity or NaN */
if (bits[0] | bits[1])
b = strcp(buf, "NaN");
else {
b = buf;
if (sign)
*b++ = '-';
b = strcp(b, "Infinity");
}
return b;
}
i = STRTOG_Normal;
}
else if (bits[0] | bits[1]) {
i = STRTOG_Denormal;
}
else {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (sign)
*b++ = '-';
#endif
*b++ = '0';
*b = 0;
return b;
}
ex -= 0x3fff + 63;
mode = 2;
if (ndig <= 0) {
if (bufsize < 32)
return 0;
mode = 0;
}
s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign);
}

764
contrib/gdtoa/gdtoa.c Normal file
View File

@ -0,0 +1,764 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
static Bigint *
#ifdef KR_headers
bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits;
#else
bitstob(ULong *bits, int nbits, int *bbits)
#endif
{
int i, k;
Bigint *b;
ULong *be, *x, *x0;
i = ULbits;
k = 0;
while(i < nbits) {
i <<= 1;
k++;
}
#ifndef Pack_32
if (!k)
k = 1;
#endif
b = Balloc(k);
be = bits + ((nbits - 1) >> kshift);
x = x0 = b->x;
do {
*x++ = *bits & ALL_ON;
#ifdef Pack_16
*x++ = (*bits >> 16) & ALL_ON;
#endif
} while(++bits <= be);
i = x - x0;
while(!x0[--i])
if (!i) {
b->wds = 0;
*bbits = 0;
goto ret;
}
b->wds = i + 1;
*bbits = i*ULbits + 32 - hi0bits(b->x[i]);
ret:
return b;
}
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
* 1. Rather than iterating, we use a simple numeric overestimate
* to determine k = floor(log10(d)). We scale relevant
* quantities using O(log2(k)) rather than O(k) multiplications.
* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
* try to generate digits strictly left to right. Instead, we
* compute with fewer bits and propagate the carry if necessary
* when rounding the final digit up. This is often faster.
* 3. Under the assumption that input will be rounded nearest,
* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
* That is, we allow equality in stopping tests when the
* round-nearest rule will give the same floating-point value
* as would satisfaction of the stopping test with strict
* inequality.
* 4. We remove common factors of powers of 2 from relevant
* quantities.
* 5. When converting floating-point integers less than 1e16,
* we use floating-point arithmetic rather than resorting
* to multiple-precision integers.
* 6. When asked to produce fewer than 15 digits, we first try
* to get by with floating-point arithmetic; we resort to
* multiple-precision integer arithmetic only if we cannot
* guarantee that the floating-point calculation has given
* the correctly rounded result. For k requested digits and
* "uniformly" distributed input, the probability is
* something like 10^(k-15) that we must resort to the Long
* calculation.
*/
char *
gdtoa
#ifdef KR_headers
(fpi, be, bits, kindp, mode, ndigits, decpt, rve)
FPI *fpi; int be; ULong *bits;
int *kindp, mode, ndigits, *decpt; char **rve;
#else
(FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
#endif
{
/* Arguments ndigits and decpt are similar to the second and third
arguments of ecvt and fcvt; trailing zeros are suppressed from
the returned string. If not null, *rve is set to point
to the end of the return value. If d is +-Infinity or NaN,
then *decpt is set to 9999.
mode:
0 ==> shortest string that yields d when read in
and rounded to nearest.
1 ==> like 0, but with Steele & White stopping rule;
e.g. with IEEE P754 arithmetic , mode 0 gives
1e23 whereas mode 1 gives 9.999999999999999e22.
2 ==> max(1,ndigits) significant digits. This gives a
return value similar to that of ecvt, except
that trailing zeros are suppressed.
3 ==> through ndigits past the decimal point. This
gives a return value similar to that from fcvt,
except that trailing zeros are suppressed, and
ndigits can be negative.
4-9 should give the same return values as 2-3, i.e.,
4 <= mode <= 9 ==> same return as mode
2 + (mode & 1). These modes are mainly for
debugging; often they run slower but sometimes
faster than modes 2-3.
4,5,8,9 ==> left-to-right digit generation.
6-9 ==> don't try fast floating-point estimate
(if applicable).
Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value
to hold the suppressed trailing zeros.
*/
int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
int rdir, s2, s5, spec_case, try_quick;
Long L;
Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
double d, d2, ds, eps;
char *s, *s0;
#ifndef MULTIPLE_THREADS
if (dtoa_result) {
freedtoa(dtoa_result);
dtoa_result = 0;
}
#endif
inex = 0;
kind = *kindp &= ~STRTOG_Inexact;
switch(kind & STRTOG_Retmask) {
case STRTOG_Zero:
goto ret_zero;
case STRTOG_Normal:
case STRTOG_Denormal:
break;
case STRTOG_Infinite:
*decpt = -32768;
return nrv_alloc("Infinity", rve, 8);
case STRTOG_NaN:
*decpt = -32768;
return nrv_alloc("NaN", rve, 3);
default:
return 0;
}
b = bitstob(bits, nbits = fpi->nbits, &bbits);
be0 = be;
if ( (i = trailz(b)) !=0) {
rshift(b, i);
be += i;
bbits -= i;
}
if (!b->wds) {
Bfree(b);
ret_zero:
*decpt = 1;
return nrv_alloc("0", rve, 1);
}
dval(d) = b2d(b, &i);
i = be + bbits - 1;
word0(d) &= Frac_mask1;
word0(d) |= Exp_11;
#ifdef IBM
if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
dval(d) /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
* log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
*
* This suggests computing an approximation k to log10(d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
*
* We want k to be too large rather than too small.
* The error in the first-order Taylor series approximation
* is in our favor, so we just round up the constant enough
* to compensate for any error in the multiplication of
* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
* adding 1e-13 to the constant term more than suffices.
* Hence we adjust the constant term to 0.1760912590558.
* (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.)
*/
#ifdef IBM
i <<= 2;
i += j;
#endif
ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
/* correct assumption about exponent range */
if ((j = i) < 0)
j = -j;
if ((j -= 1077) > 0)
ds += j * 7e-17;
k = (int)ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */
k_check = 1;
#ifdef IBM
j = be + bbits - 1;
if ( (j1 = j & 3) !=0)
dval(d) *= 1 << j1;
word0(d) += j << Exp_shift - 2 & Exp_mask;
#else
word0(d) += (be + bbits - 1) << Exp_shift;
#endif
if (k >= 0 && k <= Ten_pmax) {
if (dval(d) < tens[k])
k--;
k_check = 0;
}
j = bbits - i - 1;
if (j >= 0) {
b2 = 0;
s2 = j;
}
else {
b2 = -j;
s2 = 0;
}
if (k >= 0) {
b5 = 0;
s5 = k;
s2 += k;
}
else {
b2 -= k;
b5 = -k;
s5 = 0;
}
if (mode < 0 || mode > 9)
mode = 0;
try_quick = 1;
if (mode > 5) {
mode -= 4;
try_quick = 0;
}
leftright = 1;
switch(mode) {
case 0:
case 1:
ilim = ilim1 = -1;
i = (int)(nbits * .30103) + 3;
ndigits = 0;
break;
case 2:
leftright = 0;
/* no break */
case 4:
if (ndigits <= 0)
ndigits = 1;
ilim = ilim1 = i = ndigits;
break;
case 3:
leftright = 0;
/* no break */
case 5:
i = ndigits + k + 1;
ilim = i;
ilim1 = i - 1;
if (i <= 0)
i = 1;
}
s = s0 = rv_alloc(i);
if ( (rdir = fpi->rounding - 1) !=0) {
if (rdir < 0)
rdir = 2;
if (kind & STRTOG_Neg)
rdir = 3 - rdir;
}
/* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
#ifndef IMPRECISE_INEXACT
&& k == 0
#endif
) {
/* Try to get by with floating-point arithmetic. */
i = 0;
d2 = dval(d);
#ifdef IBM
if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
dval(d) /= 1 << j;
#endif
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
if (k > 0) {
ds = tens[k&0xf];
j = k >> 4;
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
dval(d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
if (j & 1) {
ieps++;
ds *= bigtens[i];
}
}
else {
ds = 1.;
if ( (j1 = -k) !=0) {
dval(d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
dval(d) *= bigtens[i];
}
}
}
if (k_check && dval(d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
dval(d) *= 10.;
ieps++;
}
dval(eps) = ieps*dval(d) + 7.;
word0(eps) -= (P-1)*Exp_msk1;
if (ilim == 0) {
S = mhi = 0;
dval(d) -= 5.;
if (dval(d) > dval(eps))
goto one_digit;
if (dval(d) < -dval(eps))
goto no_digits;
goto fast_failed;
}
#ifndef No_leftright
if (leftright) {
/* Use Steele & White method of only
* generating digits needed.
*/
dval(eps) = ds*0.5/tens[ilim-1] - dval(eps);
for(i = 0;;) {
L = (Long)(dval(d)/ds);
dval(d) -= L*ds;
*s++ = '0' + (int)L;
if (dval(d) < dval(eps)) {
if (dval(d))
inex = STRTOG_Inexlo;
goto ret1;
}
if (ds - dval(d) < dval(eps))
goto bump_up;
if (++i >= ilim)
break;
dval(eps) *= 10.;
dval(d) *= 10.;
}
}
else {
#endif
/* Generate ilim digits, then fix them up. */
dval(eps) *= tens[ilim-1];
for(i = 1;; i++, dval(d) *= 10.) {
if ( (L = (Long)(dval(d)/ds)) !=0)
dval(d) -= L*ds;
*s++ = '0' + (int)L;
if (i == ilim) {
ds *= 0.5;
if (dval(d) > ds + dval(eps))
goto bump_up;
else if (dval(d) < ds - dval(eps)) {
while(*--s == '0'){}
s++;
if (dval(d))
inex = STRTOG_Inexlo;
goto ret1;
}
break;
}
}
#ifndef No_leftright
}
#endif
fast_failed:
s = s0;
dval(d) = d2;
k = k0;
ilim = ilim0;
}
/* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max) {
/* Yes. */
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
if (ilim < 0 || dval(d) <= 5*ds)
goto no_digits;
goto one_digit;
}
for(i = 1;; i++, dval(d) *= 10.) {
L = dval(d) / ds;
dval(d) -= L*ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (dval(d) < 0) {
L--;
dval(d) += ds;
}
#endif
*s++ = '0' + (int)L;
if (dval(d) == 0.)
break;
if (i == ilim) {
if (rdir) {
if (rdir == 1)
goto bump_up;
inex = STRTOG_Inexlo;
goto ret1;
}
dval(d) += dval(d);
if (dval(d) > ds || dval(d) == ds && L & 1) {
bump_up:
inex = STRTOG_Inexhi;
while(*--s == '9')
if (s == s0) {
k++;
*s = '0';
break;
}
++*s++;
}
else
inex = STRTOG_Inexlo;
break;
}
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright) {
if (mode < 2) {
i = nbits - bbits;
if (be - i++ < fpi->emin)
/* denormal */
i = be - fpi->emin + 1;
}
else {
j = ilim - 1;
if (m5 >= j)
m5 -= j;
else {
s5 += j -= m5;
b5 += j;
m5 = 0;
}
if ((i = ilim) < 0) {
m2 -= i;
i = 0;
}
}
b2 += i;
s2 += i;
mhi = i2b(1);
}
if (m2 > 0 && s2 > 0) {
i = m2 < s2 ? m2 : s2;
b2 -= i;
m2 -= i;
s2 -= i;
}
if (b5 > 0) {
if (leftright) {
if (m5 > 0) {
mhi = pow5mult(mhi, m5);
b1 = mult(mhi, b);
Bfree(b);
b = b1;
}
if ( (j = b5 - m5) !=0)
b = pow5mult(b, j);
}
else
b = pow5mult(b, b5);
}
S = i2b(1);
if (s5 > 0)
S = pow5mult(S, s5);
/* Check for special case that d is a normalized power of 2. */
spec_case = 0;
if (mode < 2) {
if (bbits == 1 && be0 > fpi->emin + 1) {
/* The special case */
b2++;
s2++;
spec_case = 1;
}
}
/* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits.
*
* Perhaps we should just compute leading 28 bits of S once
* and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q.
*/
#ifdef Pack_32
if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0)
i = 32 - i;
#else
if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0)
i = 16 - i;
#endif
if (i > 4) {
i -= 4;
b2 += i;
m2 += i;
s2 += i;
}
else if (i < 4) {
i += 28;
b2 += i;
m2 += i;
s2 += i;
}
if (b2 > 0)
b = lshift(b, b2);
if (s2 > 0)
S = lshift(S, s2);
if (k_check) {
if (cmp(b,S) < 0) {
k--;
b = multadd(b, 10, 0); /* we botched the k estimate */
if (leftright)
mhi = multadd(mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && mode > 2) {
if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
/* no digits, fcvt style */
no_digits:
k = -1 - ndigits;
inex = STRTOG_Inexlo;
goto ret;
}
one_digit:
inex = STRTOG_Inexhi;
*s++ = '1';
k++;
goto ret;
}
if (leftright) {
if (m2 > 0)
mhi = lshift(mhi, m2);
/* Compute mlo -- check for special case
* that d is a normalized power of 2.
*/
mlo = mhi;
if (spec_case) {
mhi = Balloc(mhi->k);
Bcopy(mhi, mlo);
mhi = lshift(mhi, 1);
}
for(i = 1;;i++) {
dig = quorem(b,S) + '0';
/* Do we yet have the shortest decimal string
* that will round to d?
*/
j = cmp(b, mlo);
delta = diff(S, mhi);
j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(delta);
#ifndef ROUND_BIASED
if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
if (dig == '9')
goto round_9_up;
if (j <= 0) {
if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo;
}
else {
dig++;
inex = STRTOG_Inexhi;
}
*s++ = dig;
goto ret;
}
#endif
if (j < 0 || j == 0 && !mode
#ifndef ROUND_BIASED
&& !(bits[0] & 1)
#endif
) {
if (rdir && (b->wds > 1 || b->x[0])) {
if (rdir == 2) {
inex = STRTOG_Inexlo;
goto accept;
}
while (cmp(S,mhi) > 0) {
*s++ = dig;
mhi1 = multadd(mhi, 10, 0);
if (mlo == mhi)
mlo = mhi1;
mhi = mhi1;
b = multadd(b, 10, 0);
dig = quorem(b,S) + '0';
}
if (dig++ == '9')
goto round_9_up;
inex = STRTOG_Inexhi;
goto accept;
}
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
if ((j1 > 0 || j1 == 0 && dig & 1)
&& dig++ == '9')
goto round_9_up;
inex = STRTOG_Inexhi;
}
if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo;
accept:
*s++ = dig;
goto ret;
}
if (j1 > 0 && rdir != 2) {
if (dig == '9') { /* possible if i == 1 */
round_9_up:
*s++ = '9';
inex = STRTOG_Inexhi;
goto roundoff;
}
inex = STRTOG_Inexhi;
*s++ = dig + 1;
goto ret;
}
*s++ = dig;
if (i == ilim)
break;
b = multadd(b, 10, 0);
if (mlo == mhi)
mlo = mhi = multadd(mhi, 10, 0);
else {
mlo = multadd(mlo, 10, 0);
mhi = multadd(mhi, 10, 0);
}
}
}
else
for(i = 1;; i++) {
*s++ = dig = quorem(b,S) + '0';
if (i >= ilim)
break;
b = multadd(b, 10, 0);
}
/* Round off last digit */
if (rdir) {
if (rdir == 2 || b->wds <= 1 && !b->x[0])
goto chopzeros;
goto roundoff;
}
b = lshift(b, 1);
j = cmp(b, S);
if (j > 0 || j == 0 && dig & 1) {
roundoff:
inex = STRTOG_Inexhi;
while(*--s == '9')
if (s == s0) {
k++;
*s++ = '1';
goto ret;
}
++*s++;
}
else {
chopzeros:
if (b->wds > 1 || b->x[0])
inex = STRTOG_Inexlo;
while(*--s == '0'){}
s++;
}
ret:
Bfree(S);
if (mhi) {
if (mlo && mlo != mhi)
Bfree(mlo);
Bfree(mhi);
}
ret1:
Bfree(b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
*kindp |= inex;
return s0;
}

159
contrib/gdtoa/gdtoa.h Normal file
View File

@ -0,0 +1,159 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#ifndef GDTOA_H_INCLUDED
#define GDTOA_H_INCLUDED
#include "arith.h"
#ifndef Long
#define Long long
#endif
#ifndef ULong
typedef unsigned Long ULong;
#endif
#ifndef UShort
typedef unsigned short UShort;
#endif
#ifndef ANSI
#ifdef KR_headers
#define ANSI(x) ()
#define Void /*nothing*/
#else
#define ANSI(x) x
#define Void void
#endif
#endif /* ANSI */
#ifndef CONST
#ifdef KR_headers
#define CONST /* blank */
#else
#define CONST const
#endif
#endif /* CONST */
enum { /* return values from strtodg */
STRTOG_Zero = 0,
STRTOG_Normal = 1,
STRTOG_Denormal = 2,
STRTOG_Infinite = 3,
STRTOG_NaN = 4,
STRTOG_NaNbits = 5,
STRTOG_NoNumber = 6,
STRTOG_Retmask = 7,
/* The following may be or-ed into one of the above values. */
STRTOG_Neg = 0x08,
STRTOG_Inexlo = 0x10,
STRTOG_Inexhi = 0x20,
STRTOG_Inexact = 0x30,
STRTOG_Underflow= 0x40,
STRTOG_Overflow = 0x80
};
typedef struct
FPI {
int nbits;
int emin;
int emax;
int rounding;
int sudden_underflow;
} FPI;
enum { /* FPI.rounding values: same as FLT_ROUNDS */
FPI_Round_zero = 0,
FPI_Round_near = 1,
FPI_Round_up = 2,
FPI_Round_down = 3
};
#ifdef __cplusplus
extern "C" {
#endif
extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt,
int *sign, char **rve));
extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
int mode, int ndigits, int *decpt, char **rve));
extern void freedtoa ANSI((char*));
extern float strtof ANSI((CONST char *, char **));
extern double strtod ANSI((CONST char *, char **));
extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
extern char* g_ddfmt ANSI((char*, double*, int, unsigned));
extern char* g_dfmt ANSI((char*, double*, int, unsigned));
extern char* g_ffmt ANSI((char*, float*, int, unsigned));
extern char* g_Qfmt ANSI((char*, void*, int, unsigned));
extern char* g_xfmt ANSI((char*, void*, int, unsigned));
extern char* g_xLfmt ANSI((char*, void*, int, unsigned));
extern int strtoId ANSI((CONST char*, char**, double*, double*));
extern int strtoIdd ANSI((CONST char*, char**, double*, double*));
extern int strtoIf ANSI((CONST char*, char**, float*, float*));
extern int strtoIQ ANSI((CONST char*, char**, void*, void*));
extern int strtoIx ANSI((CONST char*, char**, void*, void*));
extern int strtoIxL ANSI((CONST char*, char**, void*, void*));
extern int strtord ANSI((CONST char*, char**, int, double*));
extern int strtordd ANSI((CONST char*, char**, int, double*));
extern int strtorf ANSI((CONST char*, char**, int, float*));
extern int strtorQ ANSI((CONST char*, char**, int, void*));
extern int strtorx ANSI((CONST char*, char**, int, void*));
extern int strtorxL ANSI((CONST char*, char**, int, void*));
#if 1
extern int strtodI ANSI((CONST char*, char**, double*));
extern int strtopd ANSI((CONST char*, char**, double*));
extern int strtopdd ANSI((CONST char*, char**, double*));
extern int strtopf ANSI((CONST char*, char**, float*));
extern int strtopQ ANSI((CONST char*, char**, void*));
extern int strtopx ANSI((CONST char*, char**, void*));
extern int strtopxL ANSI((CONST char*, char**, void*));
#else
#define strtopd(s,se,x) strtord(s,se,1,x)
#define strtopdd(s,se,x) strtordd(s,se,1,x)
#define strtopf(s,se,x) strtorf(s,se,1,x)
#define strtopQ(s,se,x) strtorQ(s,se,1,x)
#define strtopx(s,se,x) strtorx(s,se,1,x)
#define strtopxL(s,se,x) strtorxL(s,se,1,x)
#endif
#ifdef __cplusplus
}
#endif
#endif /* GDTOA_H_INCLUDED */

614
contrib/gdtoa/gdtoaimp.h Normal file
View File

@ -0,0 +1,614 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* This is a variation on dtoa.c that converts arbitary binary
floating-point formats to and from decimal notation. It uses
double-precision arithmetic internally, so there are still
various #ifdefs that adapt the calculations to the native
double-precision arithmetic (any of IEEE, VAX D_floating,
or IBM mainframe arithmetic).
Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* 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 Sudden_Underflow for IEEE-format machines without gradual
* underflow (i.e., that flush to zero on underflow).
* #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 Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
* #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.
* #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. When converting IEEE double precision values, the
* longest string gdtoa can return is about 751 bytes long. For
* conversions by strtod of strings of 800 digits and all gdtoa
* conversions of IEEE doubles in single-threaded executions with
* 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with
* 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate.
* #define INFNAN_CHECK on IEEE systems to cause strtod to check 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,
* strtodg 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 fraction bits of the resulting NaN; if there are two or
* more strings of hexadecimal digits, each string is assigned
* to the next available sequence of 32-bit words of fractions
* bits (starting with the most significant), right-aligned in
* each sequence.
* #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 IMPRECISE_INEXACT if you do not care about the setting of
* the STRTOG_Inexact bits in the special case of doing IEEE double
* precision conversions (which could also be done by the strtog in
* dtoa.c).
* #define NO_HEX_FP to disable recognition of C9x's hexadecimal
* floating-point constants.
* #define -DNO_ERRNO to suppress setting errno (in strtod.c and
* strtodg.c).
* #define NO_STRING_H to use private versions of memcpy.
* On some K&R systems, it may also be necessary to
* #define DECLARE_SIZE_T in this case.
* #define YES_ALIAS to permit aliasing certain double values with
* arrays of ULongs. This leads to slightly better code with
* some compilers and was always used prior to 19990916, but it
* is not strictly legal and can cause trouble with aggressively
* optimizing compilers (e.g., gcc 2.95.1 under -O2).
* #define USE_LOCALE to use the current locale's decimal_point value.
*/
#ifndef GDTOAIMP_H_INCLUDED
#define GDTOAIMP_H_INCLUDED
#include "gdtoa.h"
#ifdef DEBUG
#include "stdio.h"
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif
#include "stdlib.h"
#include "string.h"
#ifdef KR_headers
#define Char char
#else
#define Char void
#endif
#ifdef MALLOC
extern Char *MALLOC ANSI((size_t));
#else
#define MALLOC malloc
#endif
#undef IEEE_Arith
#undef Avoid_Underflow
#ifdef IEEE_MC68k
#define IEEE_Arith
#endif
#ifdef IEEE_8087
#define IEEE_Arith
#endif
#include "errno.h"
#ifdef Bad_float_h
#ifdef IEEE_Arith
#define DBL_DIG 15
#define DBL_MAX_10_EXP 308
#define DBL_MAX_EXP 1024
#define FLT_RADIX 2
#define DBL_MAX 1.7976931348623157e+308
#endif
#ifdef IBM
#define DBL_DIG 16
#define DBL_MAX_10_EXP 75
#define DBL_MAX_EXP 63
#define FLT_RADIX 16
#define DBL_MAX 7.2370055773322621e+75
#endif
#ifdef VAX
#define DBL_DIG 16
#define DBL_MAX_10_EXP 38
#define DBL_MAX_EXP 127
#define FLT_RADIX 2
#define DBL_MAX 1.7014118346046923e+38
#define n_bigtens 2
#endif
#ifndef LONG_MAX
#define LONG_MAX 2147483647
#endif
#else /* ifndef Bad_float_h */
#include "float.h"
#endif /* Bad_float_h */
#ifdef IEEE_Arith
#define Scale_Bit 0x10
#define n_bigtens 5
#endif
#ifdef IBM
#define n_bigtens 3
#endif
#ifdef VAX
#define n_bigtens 2
#endif
#ifndef __MATH_H__
#include "math.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#endif
typedef union { double d; ULong L[2]; } U;
#ifdef YES_ALIAS
#define dval(x) x
#ifdef IEEE_8087
#define word0(x) ((ULong *)&x)[1]
#define word1(x) ((ULong *)&x)[0]
#else
#define word0(x) ((ULong *)&x)[0]
#define word1(x) ((ULong *)&x)[1]
#endif
#else /* !YES_ALIAS */
#ifdef IEEE_8087
#define word0(x) ((U*)&x)->L[1]
#define word1(x) ((U*)&x)->L[0]
#else
#define word0(x) ((U*)&x)->L[0]
#define word1(x) ((U*)&x)->L[1]
#endif
#define dval(x) ((U*)&x)->d
#endif /* YES_ALIAS */
/* 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)
*/
#if defined(IEEE_8087) + defined(VAX)
#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
((unsigned short *)a)[0] = (unsigned short)c, a++)
#else
#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
((unsigned short *)a)[1] = (unsigned short)c, a++)
#endif
/* #define P DBL_MANT_DIG */
/* Ten_pmax = floor(P*log(2)/log(5)) */
/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
#ifdef IEEE_Arith
#define Exp_shift 20
#define Exp_shift1 20
#define Exp_msk1 0x100000
#define Exp_msk11 0x100000
#define Exp_mask 0x7ff00000
#define P 53
#define Bias 1023
#define Emin (-1022)
#define Exp_1 0x3ff00000
#define Exp_11 0x3ff00000
#define Ebits 11
#define Frac_mask 0xfffff
#define Frac_mask1 0xfffff
#define Ten_pmax 22
#define Bletch 0x10
#define Bndry_mask 0xfffff
#define Bndry_mask1 0xfffff
#define LSB 1
#define Sign_bit 0x80000000
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 14
#define Int_max 14
#ifndef Flt_Rounds
#ifdef FLT_ROUNDS
#define Flt_Rounds FLT_ROUNDS
#else
#define Flt_Rounds 1
#endif
#endif /*Flt_Rounds*/
#else /* ifndef IEEE_Arith */
#undef Sudden_Underflow
#define Sudden_Underflow
#ifdef IBM
#undef Flt_Rounds
#define Flt_Rounds 0
#define Exp_shift 24
#define Exp_shift1 24
#define Exp_msk1 0x1000000
#define Exp_msk11 0x1000000
#define Exp_mask 0x7f000000
#define P 14
#define Bias 65
#define Exp_1 0x41000000
#define Exp_11 0x41000000
#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
#define Frac_mask 0xffffff
#define Frac_mask1 0xffffff
#define Bletch 4
#define Ten_pmax 22
#define Bndry_mask 0xefffff
#define Bndry_mask1 0xffffff
#define LSB 1
#define Sign_bit 0x80000000
#define Log2P 4
#define Tiny0 0x100000
#define Tiny1 0
#define Quick_max 14
#define Int_max 15
#else /* VAX */
#undef Flt_Rounds
#define Flt_Rounds 1
#define Exp_shift 23
#define Exp_shift1 7
#define Exp_msk1 0x80
#define Exp_msk11 0x800000
#define Exp_mask 0x7f80
#define P 56
#define Bias 129
#define Exp_1 0x40800000
#define Exp_11 0x4080
#define Ebits 8
#define Frac_mask 0x7fffff
#define Frac_mask1 0xffff007f
#define Ten_pmax 24
#define Bletch 2
#define Bndry_mask 0xffff007f
#define Bndry_mask1 0xffff007f
#define LSB 0x10000
#define Sign_bit 0x8000
#define Log2P 1
#define Tiny0 0x80
#define Tiny1 0
#define Quick_max 15
#define Int_max 15
#endif /* IBM, VAX */
#endif /* IEEE_Arith */
#ifndef IEEE_Arith
#define ROUND_BIASED
#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
extern double rnd_prod(), rnd_quot();
#else
extern double 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
#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
#define Big1 0xffffffff
#undef Pack_16
#ifndef Pack_32
#define Pack_32
#endif
#ifdef NO_LONG_LONG
#undef ULLong
#ifdef Just_16
#undef Pack_32
#define Pack_16
/* 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 long long
#endif
#ifndef ULLong
#define ULLong unsigned Llong
#endif
#endif /* NO_LONG_LONG */
#ifdef Pack_32
#define ULbits 32
#define kshift 5
#define kmask 31
#define ALL_ON 0xffffffff
#else
#define ULbits 16
#define kshift 4
#define kmask 15
#define ALL_ON 0xffff
#endif
#ifndef MULTIPLE_THREADS
#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
#define FREE_DTOA_LOCK(n) /*nothing*/
#endif
#define Kmax 15
struct
Bigint {
struct Bigint *next;
int k, maxwds, sign, wds;
ULong x[1];
};
typedef struct Bigint Bigint;
#ifdef NO_STRING_H
#ifdef DECLARE_SIZE_T
typedef unsigned int size_t;
#endif
extern void memcpy_D2A ANSI((void*, const void*, size_t));
#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
#else /* !NO_STRING_H */
#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
#endif /* NO_STRING_H */
#define Balloc Balloc_D2A
#define Bfree Bfree_D2A
#define ULtoQ ULtoQ_D2A
#define ULtof ULtof_D2A
#define ULtod ULtod_D2A
#define ULtodd ULtodd_D2A
#define ULtox ULtox_D2A
#define ULtoxL ULtoxL_D2A
#define any_on any_on_D2A
#define b2d b2d_D2A
#define bigtens bigtens_D2A
#define cmp cmp_D2A
#define copybits copybits_D2A
#define d2b d2b_D2A
#define decrement decrement_D2A
#define diff diff_D2A
#define dtoa_result dtoa_result_D2A
#define g__fmt g__fmt_D2A
#define gethex gethex_D2A
#define hexdig hexdig_D2A
#define hexnan hexnan_D2A
#define hi0bits hi0bits_D2A
#define i2b i2b_D2A
#define increment increment_D2A
#define lo0bits lo0bits_D2A
#define lshift lshift_D2A
#define match match_D2A
#define mult mult_D2A
#define multadd multadd_D2A
#define nrv_alloc nrv_alloc_D2A
#define pow5mult pow5mult_D2A
#define quorem quorem_D2A
#define ratio ratio_D2A
#define rshift rshift_D2A
#define rv_alloc rv_alloc_D2A
#define s2b s2b_D2A
#define set_ones set_ones_D2A
#define strcp strcp_D2A
#define strtoIg strtoIg_D2A
#define sum sum_D2A
#define tens tens_D2A
#define tinytens tinytens_D2A
#define tinytens tinytens_D2A
#define trailz trailz_D2A
#define ulp ulp_D2A
extern char *dtoa_result;
extern CONST double bigtens[], tens[], tinytens[];
extern unsigned char hexdig[];
extern Bigint *Balloc ANSI((int));
extern void Bfree ANSI((Bigint*));
extern void ULtof ANSI((ULong*, ULong*, Long, int));
extern void ULtod ANSI((ULong*, ULong*, Long, int));
extern void ULtodd ANSI((ULong*, ULong*, Long, int));
extern void ULtoQ ANSI((ULong*, ULong*, Long, int));
extern void ULtox ANSI((UShort*, ULong*, Long, int));
extern void ULtoxL ANSI((ULong*, ULong*, Long, int));
extern ULong any_on ANSI((Bigint*, int));
extern double b2d ANSI((Bigint*, int*));
extern int cmp ANSI((Bigint*, Bigint*));
extern void copybits ANSI((ULong*, int, Bigint*));
extern Bigint *d2b ANSI((double, int*, int*));
extern int decrement ANSI((Bigint*));
extern Bigint *diff ANSI((Bigint*, Bigint*));
extern char *dtoa ANSI((double d, int mode, int ndigits,
int *decpt, int *sign, char **rve));
extern char *g__fmt ANSI((char*, char*, char*, int, ULong));
extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
extern void hexdig_init_D2A(Void);
extern int hexnan ANSI((CONST char**, FPI*, ULong*));
extern int hi0bits ANSI((ULong));
extern Bigint *i2b ANSI((int));
extern Bigint *increment ANSI((Bigint*));
extern int lo0bits ANSI((ULong*));
extern Bigint *lshift ANSI((Bigint*, int));
extern int match ANSI((CONST char**, char*));
extern Bigint *mult ANSI((Bigint*, Bigint*));
extern Bigint *multadd ANSI((Bigint*, int, int));
extern char *nrv_alloc ANSI((char*, char **, int));
extern Bigint *pow5mult ANSI((Bigint*, int));
extern int quorem ANSI((Bigint*, Bigint*));
extern double ratio ANSI((Bigint*, Bigint*));
extern void rshift ANSI((Bigint*, int));
extern char *rv_alloc ANSI((int));
extern Bigint *s2b ANSI((CONST char*, int, int, ULong));
extern Bigint *set_ones ANSI((Bigint*, int));
extern char *strcp ANSI((char*, const char*));
extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*));
extern double strtod ANSI((const char *s00, char **se));
extern Bigint *sum ANSI((Bigint*, Bigint*));
extern int trailz ANSI((Bigint*));
extern double ulp ANSI((double));
#ifdef __cplusplus
}
#endif
#ifdef IEEE_Arith
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#else
#define _0 1
#define _1 0
#endif
#else
#undef INFNAN_CHECK
#endif
#ifdef INFNAN_CHECK
#ifndef NAN_WORD0
#define NAN_WORD0 0x7ff80000
#endif
#ifndef NAN_WORD1
#define NAN_WORD1 0
#endif
#endif /* INFNAN_CHECK */
#undef SI
#ifdef Sudden_Underflow
#define SI 1
#else
#define SI 0
#endif
#endif /* GDTOAIMP_H_INCLUDED */

242
contrib/gdtoa/gethex.c Normal file
View File

@ -0,0 +1,242 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
gethex(sp, fpi, exp, bp, sign)
CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign;
#else
gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
#endif
{
Bigint *b;
CONST unsigned char *decpt, *s0, *s, *s1;
int esign, havedig, irv, k, n, nbits, up;
ULong L, lostbits, *x;
Long e, e1;
if (!hexdig['0'])
hexdig_init_D2A();
havedig = 0;
s0 = *(CONST unsigned char **)sp + 2;
while(s0[havedig] == '0')
havedig++;
s0 += havedig;
s = s0;
decpt = 0;
if (!hexdig[*s]) {
if (*s == '.') {
decpt = ++s;
if (!hexdig[*s])
goto ret0;
}
else {
ret0:
*sp = (char*)s;
return havedig ? STRTOG_Zero : STRTOG_NoNumber;
}
while(*s == '0')
s++;
havedig = 1;
if (!hexdig[*s])
goto ret0;
s0 = s;
}
while(hexdig[*s])
s++;
if (*s == '.' && !decpt) {
decpt = ++s;
while(hexdig[*s])
s++;
}
e = 0;
if (decpt)
e = -(((Long)(s-decpt)) << 2);
s1 = s;
switch(*s) {
case 'p':
case 'P':
esign = 0;
switch(*++s) {
case '-':
esign = 1;
/* no break */
case '+':
s++;
}
if ((n = hexdig[*s]) == 0 || n > 0x19) {
s = s1;
break;
}
e1 = n - 0x10;
while((n = hexdig[*++s]) !=0 && n <= 0x19)
e1 = 10*e1 + n - 0x10;
if (esign)
e1 = -e1;
e += e1;
}
*sp = (char*)s;
n = s1 - s0 - 1;
for(k = 0; n > 7; n >>= 1)
k++;
b = Balloc(k);
x = b->x;
n = 0;
L = 0;
while(s1 > s0) {
if (*--s1 == '.')
continue;
if (n == 32) {
*x++ = L;
L = 0;
n = 0;
}
L |= (hexdig[*s1] & 0x0f) << n;
n += 4;
}
*x++ = L;
b->wds = n = x - b->x;
n = 32*n - hi0bits(L);
nbits = fpi->nbits;
lostbits = 0;
x = b->x;
if (n > nbits) {
n -= nbits;
if (any_on(b,n)) {
lostbits = 1;
k = n - 1;
if (x[k>>kshift] & 1 << (k & kmask)) {
lostbits = 2;
if (k > 1 && any_on(b,k-1))
lostbits = 3;
}
}
rshift(b, n);
e += n;
}
else if (n < nbits) {
n = nbits - n;
b = lshift(b, n);
e -= n;
x = b->x;
}
if (e > fpi->emax) {
ovfl:
Bfree(b);
return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi;
}
irv = STRTOG_Normal;
if (e < fpi->emin) {
irv = STRTOG_Denormal;
n = fpi->emin - e;
if (n >= nbits) {
switch (fpi->rounding) {
case FPI_Round_near:
if (n == nbits && n < 2 || any_on(b,n-1))
goto one_bit;
break;
case FPI_Round_up:
if (!sign)
goto one_bit;
break;
case FPI_Round_down:
if (sign) {
one_bit:
*exp = fpi->emin;
x[0] = b->wds = 1;
*bp = b;
return STRTOG_Denormal | STRTOG_Inexhi
| STRTOG_Underflow;
}
}
Bfree(b);
return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow;
}
k = n - 1;
if (lostbits)
lostbits = 1;
else if (k > 0)
lostbits = any_on(b,k);
if (x[k>>kshift] & 1 << (k & kmask))
lostbits |= 2;
nbits -= n;
rshift(b,n);
e = fpi->emin;
}
if (lostbits) {
up = 0;
switch(fpi->rounding) {
case FPI_Round_zero:
break;
case FPI_Round_near:
if (lostbits & 2
&& (lostbits & 1) | x[0] & 1)
up = 1;
break;
case FPI_Round_up:
up = 1 - sign;
break;
case FPI_Round_down:
up = sign;
}
if (up) {
k = b->wds;
b = increment(b);
x = b->x;
if (b->wds > k
|| (n = nbits & kmask) !=0
&& hi0bits(x[k-1]) < 32-n) {
rshift(b,1);
if (++e > fpi->emax)
goto ovfl;
}
else if (irv == STRTOG_Denormal) {
k = nbits - 1;
if (x[k >> kshift] & 1 << (k & kmask))
irv = STRTOG_Normal;
}
irv |= STRTOG_Inexhi;
}
else
irv |= STRTOG_Inexlo;
}
*bp = b;
*exp = e;
return irv;
}

92
contrib/gdtoa/gmisc.c Normal file
View File

@ -0,0 +1,92 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
void
#ifdef KR_headers
rshift(b, k) Bigint *b; int k;
#else
rshift(Bigint *b, int k)
#endif
{
ULong *x, *x1, *xe, y;
int n;
x = x1 = b->x;
n = k >> kshift;
if (n < b->wds) {
xe = x + b->wds;
x += n;
if (k &= kmask) {
n = ULbits - k;
y = *x++ >> k;
while(x < xe) {
*x1++ = (y | (*x << n)) & ALL_ON;
y = *x++ >> k;
}
if ((*x1 = y) !=0)
x1++;
}
else
while(x < xe)
*x1++ = *x++;
}
if ((b->wds = x1 - b->x) == 0)
b->x[0] = 0;
}
int
#ifdef KR_headers
trailz(b) Bigint *b;
#else
trailz(Bigint *b)
#endif
{
ULong L, *x, *xe;
int n = 0;
x = b->x;
xe = x + b->wds;
for(n = 0; x < xe && !*x; x++)
n += ULbits;
if (x < xe) {
L = *x;
n += lo0bits(&L);
}
return n;
}

61
contrib/gdtoa/hd_init.c Normal file
View File

@ -0,0 +1,61 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
unsigned char hexdig[256];
static void
#ifdef KR_headers
htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc;
#else
htinit(unsigned char *h, unsigned char *s, int inc)
#endif
{
int i, j;
for(i = 0; (j = s[i]) !=0; i++)
h[j] = i + inc;
}
void
hexdig_init_D2A(Void)
{
#define USC (unsigned char *)
htinit(hexdig, USC "0123456789", 0x10);
htinit(hexdig, USC "abcdef", 0x10 + 10);
htinit(hexdig, USC "ABCDEF", 0x10 + 10);
}

137
contrib/gdtoa/hexnan.c Normal file
View File

@ -0,0 +1,137 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
static void
#ifdef KR_headers
L_shift(x, x1, i) ULong *x; ULong *x1; int i;
#else
L_shift(ULong *x, ULong *x1, int i)
#endif
{
int j;
i = 8 - i;
i <<= 2;
j = ULbits - i;
do {
*x |= x[1] << j;
x[1] >>= i;
} while(++x < x1);
}
int
#ifdef KR_headers
hexnan(sp, fpi, x0)
CONST char **sp; FPI *fpi; ULong *x0;
#else
hexnan( CONST char **sp, FPI *fpi, ULong *x0)
#endif
{
ULong c, h, *x, *x1, *xe;
CONST char *s;
int havedig, hd0, i, nbits;
if (!hexdig['0'])
hexdig_init_D2A();
nbits = fpi->nbits;
x = x0 + (nbits >> kshift);
if (nbits & kmask)
x++;
*--x = 0;
x1 = xe = x;
havedig = hd0 = i = 0;
s = *sp;
while(c = *(CONST unsigned char*)++s) {
if (!(h = hexdig[c])) {
if (c <= ' ') {
if (hd0 < havedig) {
if (x < x1 && i < 8)
L_shift(x, x1, i);
if (x <= x0) {
i = 8;
continue;
}
hd0 = havedig;
*--x = 0;
x1 = x;
i = 0;
}
continue;
}
if (/*(*/ c == ')' && havedig) {
*sp = s + 1;
break;
}
return STRTOG_NaN;
}
havedig++;
if (++i > 8) {
if (x <= x0)
continue;
i = 1;
*--x = 0;
}
*x = (*x << 4) | h & 0xf;
}
if (!havedig)
return STRTOG_NaN;
if (x < x1 && i < 8)
L_shift(x, x1, i);
if (x > x0) {
x1 = x0;
do *x1++ = *x++;
while(x <= xe);
do *x1++ = 0;
while(x1 <= xe);
}
else {
/* truncate high-order word if necessary */
if ( (i = nbits & (ULbits-1)) !=0)
*xe &= ((ULong)0xffffffff) >> (ULbits - i);
}
for(x1 = xe;; --x1) {
if (*x1 != 0)
break;
if (x1 == x0) {
*x1 = 1;
break;
}
}
return STRTOG_NaNbits;
}

69
contrib/gdtoa/makefile Normal file
View File

@ -0,0 +1,69 @@
# /****************************************************************
# Copyright (C) 1998 by Lucent Technologies
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that the copyright notice and this
# permission notice and warranty disclaimer appear in supporting
# documentation, and that the name of Lucent or any of its entities
# not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
# THIS SOFTWARE.
#
# ****************************************************************/
.SUFFIXES: .c .o
CC = cc
CFLAGS = -g -DINFNAN_CHECK
.c.o:
$(CC) -c $(CFLAGS) $*.c
all: arith.h gdtoa.a
arith.h: arithchk.c
$(CC) $(CFLAGS) arithchk.c || $(CC) -DNO_LONG_LONG $(CFLAGS) arithchk.c
./a.out >arith.h
rm -f a.out arithchk.o
gdtoa.a: dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c g_ffmt.c\
g_xLfmt.c g_xfmt.c gdtoa.c gethex.c gmisc.c hd_init.c hexnan.c\
misc.c smisc.c strtoIQ.c strtoId.c strtoIdd.c strtoIf.c strtoIg.c\
strtoIx.c strtoIxL.c strtod.c strtodI.c strtodg.c strtof.c strtopQ.c\
strtopd.c strtopdd.c strtopf.c strtopx.c strtopxL.c strtorQ.c\
strtord.c strtordd.c strtorf.c strtorx.c strtorxL.c sum.c ulp.c
$(CC) -c $(CFLAGS) $?
x=`echo $? | sed 's/\.c/.o/g'` && ar ruv gdtoa.a $$x && rm $$x
ranlib gdtoa.a || true
# If your system lacks ranlib, you do not need it.
xs0 = README arithchk.c dmisc.c dtoa.c g_Qfmt.c g__fmt.c g_ddfmt.c g_dfmt.c\
g_ffmt.c g_xLfmt.c g_xfmt.c gdtoa.c gdtoa.h gdtoaimp.h gethex.c\
gmisc.c hd_init.c hexnan.c makefile misc.c smisc.c strtoIQ.c\
strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c strtoIxL.c\
strtod.c strtodI.c strtodg.c strtof.c strtopQ.c strtopd.c strtopdd.c\
strtopf.c strtopx.c strtopxL.c strtorQ.c strtord.c strtordd.c\
strtorf.c strtorx.c strtorxL.c sum.c ulp.c
# "make xsum.out" to check for transmission errors; source for xsum is
# netlib's "xsum.c from f2c", e.g.,
# ftp://netlib.bell-labs.com/netlib/f2c/xsum.c.gz
xsum.out: xsum0.out $(xs0)
xsum $(xs0) >xsum1.out
cmp xsum0.out xsum1.out && mv xsum1.out xsum.out || diff xsum[01].out
clean:
rm -f arith.h *.[ao] xsum.out xsum1.out

862
contrib/gdtoa/misc.c Normal file
View File

@ -0,0 +1,862 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
static Bigint *freelist[Kmax+1];
#ifndef Omit_Private_Memory
#ifndef PRIVATE_MEM
#define PRIVATE_MEM 2304
#endif
#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
#endif
Bigint *
Balloc
#ifdef KR_headers
(k) int k;
#else
(int k)
#endif
{
int x;
Bigint *rv;
#ifndef Omit_Private_Memory
unsigned int len;
#endif
ACQUIRE_DTOA_LOCK(0);
if ( (rv = freelist[k]) !=0) {
freelist[k] = rv->next;
}
else {
x = 1 << k;
#ifdef Omit_Private_Memory
rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
#else
len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
/sizeof(double);
if (pmem_next - private_mem + len <= PRIVATE_mem) {
rv = (Bigint*)pmem_next;
pmem_next += len;
}
else
rv = (Bigint*)MALLOC(len*sizeof(double));
#endif
rv->k = k;
rv->maxwds = x;
}
FREE_DTOA_LOCK(0);
rv->sign = rv->wds = 0;
return rv;
}
void
Bfree
#ifdef KR_headers
(v) Bigint *v;
#else
(Bigint *v)
#endif
{
if (v) {
ACQUIRE_DTOA_LOCK(0);
v->next = freelist[v->k];
freelist[v->k] = v;
FREE_DTOA_LOCK(0);
}
}
int
lo0bits
#ifdef KR_headers
(y) ULong *y;
#else
(ULong *y)
#endif
{
register int k;
register 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 & 1)
return 32;
}
*y = x;
return k;
}
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 & 0xffffffffUL;
#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;
}
int
hi0bits
#ifdef KR_headers
(x) register ULong x;
#else
(register ULong x)
#endif
{
register 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;
}
Bigint *
i2b
#ifdef KR_headers
(i) int i;
#else
(int i)
#endif
{
Bigint *b;
b = Balloc(1);
b->x[0] = i;
b->wds = 1;
return b;
}
Bigint *
mult
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
{
Bigint *c;
int k, wa, wb, wc;
ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
ULong y;
#ifdef ULLong
ULLong carry, z;
#else
ULong carry, z;
#ifdef Pack_32
ULong z2;
#endif
#endif
if (a->wds < b->wds) {
c = a;
a = b;
b = c;
}
k = a->k;
wa = a->wds;
wb = b->wds;
wc = wa + wb;
if (wc > a->maxwds)
k++;
c = Balloc(k);
for(x = c->x, xa = x + wc; x < xa; x++)
*x = 0;
xa = a->x;
xae = xa + wa;
xb = b->x;
xbe = xb + wb;
xc0 = c->x;
#ifdef ULLong
for(; xb < xbe; xc0++) {
if ( (y = *xb++) !=0) {
x = xa;
xc = xc0;
carry = 0;
do {
z = *x++ * (ULLong)y + *xc + carry;
carry = z >> 32;
*xc++ = z & 0xffffffffUL;
}
while(x < xae);
*xc = carry;
}
}
#else
#ifdef Pack_32
for(; xb < xbe; xb++, xc0++) {
if ( (y = *xb & 0xffff) !=0) {
x = xa;
xc = xc0;
carry = 0;
do {
z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
carry = z >> 16;
z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
carry = z2 >> 16;
Storeinc(xc, z2, z);
}
while(x < xae);
*xc = carry;
}
if ( (y = *xb >> 16) !=0) {
x = xa;
xc = xc0;
carry = 0;
z2 = *xc;
do {
z = (*x & 0xffff) * y + (*xc >> 16) + carry;
carry = z >> 16;
Storeinc(xc, z, z2);
z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
carry = z2 >> 16;
}
while(x < xae);
*xc = z2;
}
}
#else
for(; xb < xbe; xc0++) {
if ( (y = *xb++) !=0) {
x = xa;
xc = xc0;
carry = 0;
do {
z = *x++ * y + *xc + carry;
carry = z >> 16;
*xc++ = z & 0xffff;
}
while(x < xae);
*xc = carry;
}
}
#endif
#endif
for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
c->wds = wc;
return c;
}
static Bigint *p5s;
Bigint *
pow5mult
#ifdef KR_headers
(b, k) Bigint *b; int k;
#else
(Bigint *b, int k)
#endif
{
Bigint *b1, *p5, *p51;
int i;
static int p05[3] = { 5, 25, 125 };
if ( (i = k & 3) !=0)
b = multadd(b, p05[i-1], 0);
if (!(k >>= 2))
return b;
if ((p5 = p5s) == 0) {
/* first time */
#ifdef MULTIPLE_THREADS
ACQUIRE_DTOA_LOCK(1);
if (!(p5 = p5s)) {
p5 = p5s = i2b(625);
p5->next = 0;
}
FREE_DTOA_LOCK(1);
#else
p5 = p5s = i2b(625);
p5->next = 0;
#endif
}
for(;;) {
if (k & 1) {
b1 = mult(b, p5);
Bfree(b);
b = b1;
}
if (!(k >>= 1))
break;
if ((p51 = p5->next) == 0) {
#ifdef MULTIPLE_THREADS
ACQUIRE_DTOA_LOCK(1);
if (!(p51 = p5->next)) {
p51 = p5->next = mult(p5,p5);
p51->next = 0;
}
FREE_DTOA_LOCK(1);
#else
p51 = p5->next = mult(p5,p5);
p51->next = 0;
#endif
}
p5 = p51;
}
return b;
}
Bigint *
lshift
#ifdef KR_headers
(b, k) Bigint *b; int k;
#else
(Bigint *b, int k)
#endif
{
int i, k1, n, n1;
Bigint *b1;
ULong *x, *x1, *xe, z;
n = k >> kshift;
k1 = b->k;
n1 = n + b->wds + 1;
for(i = b->maxwds; n1 > i; i <<= 1)
k1++;
b1 = Balloc(k1);
x1 = b1->x;
for(i = 0; i < n; i++)
*x1++ = 0;
x = b->x;
xe = x + b->wds;
if (k &= kmask) {
#ifdef Pack_32
k1 = 32 - k;
z = 0;
do {
*x1++ = *x << k | z;
z = *x++ >> k1;
}
while(x < xe);
if ((*x1 = z) !=0)
++n1;
#else
k1 = 16 - k;
z = 0;
do {
*x1++ = *x << k & 0xffff | z;
z = *x++ >> k1;
}
while(x < xe);
if (*x1 = z)
++n1;
#endif
}
else do
*x1++ = *x++;
while(x < xe);
b1->wds = n1 - 1;
Bfree(b);
return b1;
}
int
cmp
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
{
ULong *xa, *xa0, *xb, *xb0;
int i, j;
i = a->wds;
j = b->wds;
#ifdef DEBUG
if (i > 1 && !a->x[i-1])
Bug("cmp called with a->x[a->wds-1] == 0");
if (j > 1 && !b->x[j-1])
Bug("cmp called with b->x[b->wds-1] == 0");
#endif
if (i -= j)
return i;
xa0 = a->x;
xa = xa0 + j;
xb0 = b->x;
xb = xb0 + j;
for(;;) {
if (*--xa != *--xb)
return *xa < *xb ? -1 : 1;
if (xa <= xa0)
break;
}
return 0;
}
Bigint *
diff
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
{
Bigint *c;
int i, wa, wb;
ULong *xa, *xae, *xb, *xbe, *xc;
#ifdef ULLong
ULLong borrow, y;
#else
ULong borrow, y;
#ifdef Pack_32
ULong z;
#endif
#endif
i = cmp(a,b);
if (!i) {
c = Balloc(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(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 & 1UL;
*xc++ = y & 0xffffffffUL;
}
while(xb < xbe);
while(xa < xae) {
y = *xa++ - borrow;
borrow = y >> 32 & 1UL;
*xc++ = y & 0xffffffffUL;
}
#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;
}
double
b2d
#ifdef KR_headers
(a, e) Bigint *a; int *e;
#else
(Bigint *a, int *e)
#endif
{
ULong *xa, *xa0, w, y, z;
int k;
double d;
#ifdef VAX
ULong d0, d1;
#else
#define d0 word0(d)
#define d1 word1(d)
#endif
xa0 = a->x;
xa = xa0 + a->wds;
y = *--xa;
#ifdef DEBUG
if (!y) Bug("zero y in b2d");
#endif
k = hi0bits(y);
*e = 32 - k;
#ifdef Pack_32
if (k < Ebits) {
d0 = Exp_1 | y >> Ebits - k;
w = xa > xa0 ? *--xa : 0;
d1 = y << (32-Ebits) + k | w >> Ebits - k;
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
if (k -= Ebits) {
d0 = Exp_1 | y << k | z >> 32 - k;
y = xa > xa0 ? *--xa : 0;
d1 = z << k | y >> 32 - k;
}
else {
d0 = Exp_1 | y;
d1 = z;
}
#else
if (k < Ebits + 16) {
z = xa > xa0 ? *--xa : 0;
d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
w = xa > xa0 ? *--xa : 0;
y = xa > xa0 ? *--xa : 0;
d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
w = xa > xa0 ? *--xa : 0;
k -= Ebits + 16;
d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
y = xa > xa0 ? *--xa : 0;
d1 = w << k + 16 | y << k;
#endif
ret_d:
#ifdef VAX
word0(d) = d0 >> 16 | d0 << 16;
word1(d) = d1 >> 16 | d1 << 16;
#endif
return dval(d);
}
#undef d0
#undef d1
Bigint *
d2b
#ifdef KR_headers
(d, e, bits) double d; int *e, *bits;
#else
(double d, int *e, int *bits)
#endif
{
Bigint *b;
int de, i, k;
ULong *x, y, z;
#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(1);
#else
b = Balloc(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)) !=0)
z |= Exp_msk1;
#endif
#ifdef Pack_32
if ( (y = d1) !=0) {
if ( (k = lo0bits(&y)) !=0) {
x[0] = y | z << 32 - k;
z >>= k;
}
else
x[0] = y;
i = b->wds = (x[1] = z) !=0 ? 2 : 1;
}
else {
#ifdef DEBUG
if (!z)
Bug("Zero passed to d2b");
#endif
k = lo0bits(&z);
x[0] = z;
i = b->wds = 1;
k += 32;
}
#else
if ( (y = d1) !=0) {
if ( (k = lo0bits(&y)) !=0)
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
CONST double
#ifdef IEEE_Arith
bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256
};
#else
#ifdef IBM
bigtens[] = { 1e16, 1e32, 1e64 };
CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
#else
bigtens[] = { 1e16, 1e32 };
CONST double tinytens[] = { 1e-16, 1e-32 };
#endif
#endif
CONST double
tens[] = {
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22
#ifdef VAX
, 1e23, 1e24
#endif
};
char *
#ifdef KR_headers
strcp_D2A(a, b) char *a; char *b;
#else
strcp_D2A(char *a, CONST char *b)
#endif
{
while(*a = *b++)
a++;
return a;
}
#ifdef NO_STRING_H
Char *
#ifdef KR_headers
memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
#else
memcpy_D2A(void *a1, void *b1, size_t len)
#endif
{
register char *a = (char*)a1, *ae = a + len;
register char *b = (char*)b1, *a0 = a;
while(a < ae)
*a++ = *b++;
return a0;
}
#endif /* NO_STRING_H */

197
contrib/gdtoa/smisc.c Normal file
View File

@ -0,0 +1,197 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
Bigint *
s2b
#ifdef KR_headers
(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9;
#else
(CONST char *s, int nd0, int nd, ULong y9)
#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++;
}
else
s += 10;
for(; i < nd; i++)
b = multadd(b, 10, *s++ - '0');
return b;
}
double
ratio
#ifdef KR_headers
(a, b) Bigint *a, *b;
#else
(Bigint *a, Bigint *b)
#endif
{
double da, db;
int k, ka, kb;
dval(da) = b2d(a, &ka);
dval(db) = b2d(b, &kb);
k = ka - kb + ULbits*(a->wds - b->wds);
#ifdef IBM
if (k > 0) {
word0(da) += (k >> 2)*Exp_msk1;
if (k &= 3)
dval(da) *= 1 << k;
}
else {
k = -k;
word0(db) += (k >> 2)*Exp_msk1;
if (k &= 3)
dval(db) *= 1 << k;
}
#else
if (k > 0)
word0(da) += k*Exp_msk1;
else {
k = -k;
word0(db) += k*Exp_msk1;
}
#endif
return dval(da) / dval(db);
}
#ifdef INFNAN_CHECK
int
match
#ifdef KR_headers
(sp, t) char **sp, *t;
#else
(CONST char **sp, char *t)
#endif
{
int c, d;
CONST char *s = *sp;
while( (d = *t++) !=0) {
if ((c = *++s) >= 'A' && c <= 'Z')
c += 'a' - 'A';
if (c != d)
return 0;
}
*sp = s + 1;
return 1;
}
#endif /* INFNAN_CHECK */
void
#ifdef KR_headers
copybits(c, n, b) ULong *c; int n; Bigint *b;
#else
copybits(ULong *c, int n, Bigint *b)
#endif
{
ULong *ce, *x, *xe;
#ifdef Pack_16
int nw, nw1;
#endif
ce = c + ((n-1) >> kshift) + 1;
x = b->x;
#ifdef Pack_32
xe = x + b->wds;
while(x < xe)
*c++ = *x++;
#else
nw = b->wds;
nw1 = nw & 1;
for(xe = x + (nw - nw1); x < xe; x += 2)
Storeinc(c, x[1], x[0]);
if (nw1)
*c++ = *x;
#endif
while(c < ce)
*c++ = 0;
}
ULong
#ifdef KR_headers
any_on(b, k) Bigint *b; int k;
#else
any_on(Bigint *b, int k)
#endif
{
int n, nwds;
ULong *x, *x0, x1, x2;
x = b->x;
nwds = b->wds;
n = k >> kshift;
if (n > nwds)
n = nwds;
else if (n < nwds && (k &= kmask)) {
x1 = x2 = x[n];
x1 >>= k;
x1 <<= k;
if (x1 != x2)
return 1;
}
x0 = x;
x += n;
while(x > x0)
if (*--x)
return 1;
return 0;
}

69
contrib/gdtoa/strtoIQ.c Normal file
View File

@ -0,0 +1,69 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
strtoIQ(CONST char *s, char **sp, void *a, void *b)
#endif
{
static FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI };
Long exp[2];
Bigint *B[2];
int k, rv[2];
ULong *L = (ULong *)a, *M = (ULong *)b;
B[0] = Balloc(2);
B[0]->wds = 4;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtoQ(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtoQ(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else {
M[0] = L[0];
M[1] = L[1];
M[2] = L[2];
M[3] = L[3];
}
return k;
}

66
contrib/gdtoa/strtoId.c Normal file
View File

@ -0,0 +1,66 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
#else
strtoId(CONST char *s, char **sp, double *f0, double *f1)
#endif
{
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
Long exp[2];
Bigint *B[2];
int k, rv[2];
B[0] = Balloc(1);
B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else {
((ULong*)f1)[0] = ((ULong*)f0)[0];
((ULong*)f1)[1] = ((ULong*)f0)[1];
}
return k;
}

72
contrib/gdtoa/strtoIdd.c Normal file
View File

@ -0,0 +1,72 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1;
#else
strtoIdd(CONST char *s, char **sp, double *f0, double *f1)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
#else
static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
#endif
Long exp[2];
Bigint *B[2];
int k, rv[2];
B[0] = Balloc(2);
B[0]->wds = 4;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else {
((ULong*)f1)[0] = ((ULong*)f0)[0];
((ULong*)f1)[1] = ((ULong*)f0)[1];
((ULong*)f1)[2] = ((ULong*)f0)[2];
((ULong*)f1)[3] = ((ULong*)f0)[3];
}
return k;
}

64
contrib/gdtoa/strtoIf.c Normal file
View File

@ -0,0 +1,64 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1;
#else
strtoIf(CONST char *s, char **sp, float *f0, float *f1)
#endif
{
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
Long exp[2];
Bigint *B[2];
int k, rv[2];
B[0] = Balloc(0);
B[0]->wds = 1;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else
*(ULong*)f1 = *(ULong*)f0;
return k;
}

139
contrib/gdtoa/strtoIg.c Normal file
View File

@ -0,0 +1,139 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp;
#else
strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp)
#endif
{
Bigint *b, *b1;
int i, nb, nw, nw1, rv, rv1, swap;
unsigned int nb1, nb11;
Long e1;
b = *B;
rv = strtodg(s00, se, fpi, exp, b->x);
if (!(rv & STRTOG_Inexact)) {
B[1] = 0;
return *rvp = rv;
}
e1 = exp[0];
rv1 = rv ^ STRTOG_Inexact;
b1 = Balloc(b->k);
Bcopy(b1, b);
nb = fpi->nbits;
nb1 = nb & 31;
nb11 = (nb1 - 1) & 31;
nw = b->wds;
nw1 = nw - 1;
if (rv & STRTOG_Inexlo) {
swap = 0;
b1 = increment(b1);
if (fpi->sudden_underflow
&& (rv & STRTOG_Retmask) == STRTOG_Zero) {
b1->x[0] = 0;
b1->x[nw1] = 1L << nb11;
rv1 += STRTOG_Normal - STRTOG_Zero;
rv1 &= ~STRTOG_Underflow;
goto swapcheck;
}
if (b1->wds > nw
|| nb1 && b1->x[nw1] & 1L << nb1) {
if (++e1 > fpi->emax)
rv1 = STRTOG_Infinite | STRTOG_Inexhi;
rshift(b1, 1);
}
else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
if (b1->x[nw1] & 1L << nb11) {
rv1 += STRTOG_Normal - STRTOG_Denormal;
rv1 &= ~STRTOG_Underflow;
}
}
}
else {
swap = STRTOG_Neg;
if ((rv & STRTOG_Retmask) == STRTOG_Infinite) {
b1 = set_ones(b1, nb);
e1 = fpi->emax;
rv1 = STRTOG_Normal | STRTOG_Inexlo;
goto swapcheck;
}
decrement(b1);
if ((rv & STRTOG_Retmask) == STRTOG_Denormal) {
for(i = nw1; !b1->x[i]; --i)
if (!i) {
rv1 = STRTOG_Zero | STRTOG_Inexlo;
break;
}
goto swapcheck;
}
if (!(b1->x[nw1] & 1L << nb11)) {
if (e1 == fpi->emin) {
if (fpi->sudden_underflow)
rv1 += STRTOG_Zero - STRTOG_Normal;
else
rv1 += STRTOG_Denormal - STRTOG_Normal;
rv1 |= STRTOG_Underflow;
}
else {
b1 = lshift(b1, 1);
b1->x[0] |= 1;
--e1;
}
}
}
swapcheck:
if (swap ^ (rv & STRTOG_Neg)) {
rvp[0] = rv1;
rvp[1] = rv;
B[0] = b1;
B[1] = b;
exp[1] = exp[0];
exp[0] = e1;
}
else {
rvp[0] = rv;
rvp[1] = rv1;
B[1] = b1;
exp[1] = e1;
}
return rv;
}

70
contrib/gdtoa/strtoIx.c Normal file
View File

@ -0,0 +1,70 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
strtoIx(CONST char *s, char **sp, void *a, void *b)
#endif
{
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
Long exp[2];
Bigint *B[2];
int k, rv[2];
UShort *L = (UShort *)a, *M = (UShort *)b;
B[0] = Balloc(1);
B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtox(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtox(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else {
M[0] = L[0];
M[1] = L[1];
M[2] = L[2];
M[3] = L[3];
M[4] = L[4];
}
return k;
}

68
contrib/gdtoa/strtoIxL.c Normal file
View File

@ -0,0 +1,68 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b;
#else
strtoIxL(CONST char *s, char **sp, void *a, void *b)
#endif
{
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
Long exp[2];
Bigint *B[2];
int k, rv[2];
ULong *L = (ULong *)a, *M = (ULong *)b;
B[0] = Balloc(1);
B[0]->wds = 2;
k = strtoIg(s, sp, &fpi, exp, B, rv);
ULtoxL(L, B[0]->x, exp[0], rv[0]);
Bfree(B[0]);
if (B[1]) {
ULtoxL(M, B[1]->x, exp[1], rv[1]);
Bfree(B[1]);
}
else {
M[0] = L[0];
M[1] = L[1];
M[2] = L[2];
}
return k;
}

985
contrib/gdtoa/strtod.c Normal file
View File

@ -0,0 +1,985 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#ifdef USE_LOCALE
#include "locale.h"
#endif
#ifdef IEEE_Arith
#ifndef NO_IEEE_Scale
#define Avoid_Underflow
#undef tinytens
/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
/* flag unnecessarily. It leads to a song and dance at the end of strtod. */
static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
9007199254740992.e-256
};
#endif
#endif
#ifdef Honor_FLT_ROUNDS
#define Rounding rounding
#undef Check_FLT_ROUNDS
#define Check_FLT_ROUNDS
#else
#define Rounding Flt_Rounds
#endif
double
strtod
#ifdef KR_headers
(s00, se) CONST char *s00; char **se;
#else
(CONST char *s00, char **se)
#endif
{
#ifdef Avoid_Underflow
int scale;
#endif
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
CONST char *s, *s0, *s1;
double aadj, aadj1, adj, rv, rv0;
Long L;
ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
#ifdef Honor_FLT_ROUNDS
int rounding;
#endif
#ifdef USE_LOCALE
CONST char *s2;
#endif
sign = nz0 = nz = 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
{
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
Long exp;
ULong bits[2];
switch(s[1]) {
case 'x':
case 'X':
switch(gethex(&s, &fpi, &exp, &bb, sign)) {
case STRTOG_NoNumber:
s = s00;
sign = 0;
case STRTOG_Zero:
break;
default:
copybits(bits, fpi.nbits, bb);
Bfree(bb);
ULtod(((U*)&rv)->L, bits, exp, i);
}
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';
else if (nd < 16)
z = 10*z + c - '0';
nd0 = nd;
#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;
if (!nd) {
for(; c == '0'; c = *++s)
nz++;
if (c > '0' && c <= '9') {
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;
else if (nd <= DBL_DIG + 1)
z *= 10;
if (nd++ < 9)
y = 10*y + c;
else if (nd <= DBL_DIG + 1)
z = 10*z + c;
nz = 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 */
ULong bits[2];
static FPI fpinan = /* only 52 explicit bits */
{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
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")) {
#ifndef No_Hex_NaN
if (*s == '(' /*)*/
&& hexnan(&s, &fpinan, bits)
== STRTOG_NaNbits) {
word0(rv) = 0x7ff00000 | bits[1];
word1(rv) = bits[0];
}
else {
word0(rv) = NAN_WORD0;
word1(rv) = NAN_WORD1;
}
#endif
goto ret;
}
}
#endif /* INFNAN_CHECK */
ret0:
s = s00;
sign = 0;
}
goto ret;
}
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;
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 = -rv;
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 = -rv;
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
else if (e >= -Ten_pmax) {
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
rv = -rv;
sign = 0;
}
#endif
/* rv = */ rounded_quotient(dval(rv), tens[-e]);
goto ret;
}
#endif
}
e1 += nd - k;
#ifdef IEEE_Arith
#ifdef SET_INEXACT
inexact = 1;
if (k <= DBL_DIG)
oldinexact = get_inexact();
#endif
#ifdef Avoid_Underflow
scale = 0;
#endif
#ifdef Honor_FLT_ROUNDS
if ((rounding = Flt_Rounds) >= 2) {
if (sign)
rounding = rounding == 2 ? 0 : 2;
else
if (rounding != 2)
rounding = 0;
}
#endif
#endif /*IEEE_Arith*/
/* Get starting approximation = rv * 10**e1 */
if (e1 > 0) {
if ( (i = e1 & 15) !=0)
dval(rv) *= tens[i];
if (e1 &= ~15) {
if (e1 > DBL_MAX_10_EXP) {
ovfl:
#ifndef NO_ERRNO
errno = ERANGE;
#endif
/* Can't trust HUGE_VAL */
#ifdef IEEE_Arith
#ifdef Honor_FLT_ROUNDS
switch(rounding) {
case 0: /* toward 0 */
case 3: /* toward -infinity */
word0(rv) = Big0;
word1(rv) = Big1;
break;
default:
word0(rv) = Exp_mask;
word1(rv) = 0;
}
#else /*Honor_FLT_ROUNDS*/
word0(rv) = Exp_mask;
word1(rv) = 0;
#endif /*Honor_FLT_ROUNDS*/
#ifdef SET_INEXACT
/* set overflow bit */
dval(rv0) = 1e300;
dval(rv0) *= dval(rv0);
#endif
#else /*IEEE_Arith*/
word0(rv) = Big0;
word1(rv) = Big1;
#endif /*IEEE_Arith*/
if (bd0)
goto retfree;
goto ret;
}
e1 >>= 4;
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
dval(rv) *= bigtens[j];
/* The last multiplication could overflow. */
word0(rv) -= P*Exp_msk1;
dval(rv) *= bigtens[j];
if ((z = word0(rv) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-P))
goto ovfl;
if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
/* set to largest number */
/* (Can't trust DBL_MAX) */
word0(rv) = Big0;
word1(rv) = Big1;
}
else
word0(rv) += P*Exp_msk1;
}
}
else if (e1 < 0) {
e1 = -e1;
if ( (i = e1 & 15) !=0)
dval(rv) /= tens[i];
if (e1 >>= 4) {
if (e1 >= 1 << n_bigtens)
goto undfl;
#ifdef Avoid_Underflow
if (e1 & Scale_Bit)
scale = 2*P;
for(j = 0; e1 > 0; j++, e1 >>= 1)
if (e1 & 1)
dval(rv) *= tinytens[j];
if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
>> Exp_shift)) > 0) {
/* scaled rv is denormal; zap j low bits */
if (j >= 32) {
word1(rv) = 0;
if (j >= 53)
word0(rv) = (P+2)*Exp_msk1;
else
word0(rv) &= 0xffffffff << j-32;
}
else
word1(rv) &= 0xffffffff << j;
}
#else
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
dval(rv) *= tinytens[j];
/* The last multiplication could underflow. */
dval(rv0) = dval(rv);
dval(rv) *= tinytens[j];
if (!dval(rv)) {
dval(rv) = 2.*dval(rv0);
dval(rv) *= tinytens[j];
#endif
if (!dval(rv)) {
undfl:
dval(rv) = 0.;
#ifndef NO_ERRNO
errno = ERANGE;
#endif
if (bd0)
goto retfree;
goto ret;
}
#ifndef Avoid_Underflow
word0(rv) = Tiny0;
word1(rv) = Tiny1;
/* The refinement below will clean
* this approximation up.
*/
}
#endif
}
}
/* Now the hard part -- adjusting rv to the correct value.*/
/* Put digits into bd: true value = bd * 10^e */
bd0 = s2b(s0, nd0, nd, y);
for(;;) {
bd = Balloc(bd0->k);
Bcopy(bd, bd0);
bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
bs = i2b(1);
if (e >= 0) {
bb2 = bb5 = 0;
bd2 = bd5 = e;
}
else {
bb2 = bb5 = -e;
bd2 = bd5 = 0;
}
if (bbe >= 0)
bb2 += bbe;
else
bd2 -= bbe;
bs2 = bb2;
#ifdef Honor_FLT_ROUNDS
if (rounding != 1)
bs2++;
#endif
#ifdef Avoid_Underflow
j = bbe - scale;
i = j + bbbits - 1; /* logb(rv) */
if (i < Emin) /* denormal */
j += P - Emin;
else
j = P + 1 - bbbits;
#else /*Avoid_Underflow*/
#ifdef Sudden_Underflow
#ifdef IBM
j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
#else
j = P + 1 - bbbits;
#endif
#else /*Sudden_Underflow*/
j = bbe;
i = j + bbbits - 1; /* logb(rv) */
if (i < Emin) /* denormal */
j += P - Emin;
else
j = P + 1 - bbbits;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
bb2 += j;
bd2 += j;
#ifdef Avoid_Underflow
bd2 += scale;
#endif
i = bb2 < bd2 ? bb2 : bd2;
if (i > bs2)
i = bs2;
if (i > 0) {
bb2 -= i;
bd2 -= i;
bs2 -= i;
}
if (bb5 > 0) {
bs = pow5mult(bs, bb5);
bb1 = mult(bs, bb);
Bfree(bb);
bb = bb1;
}
if (bb2 > 0)
bb = lshift(bb, bb2);
if (bd5 > 0)
bd = pow5mult(bd, bd5);
if (bd2 > 0)
bd = lshift(bd, bd2);
if (bs2 > 0)
bs = lshift(bs, bs2);
delta = diff(bb, bd);
dsign = delta->sign;
delta->sign = 0;
i = cmp(delta, bs);
#ifdef Honor_FLT_ROUNDS
if (rounding != 1) {
if (i < 0) {
/* Error is less than an ulp */
if (!delta->x[0] && delta->wds <= 1) {
/* exact */
#ifdef SET_INEXACT
inexact = 0;
#endif
break;
}
if (rounding) {
if (dsign) {
adj = 1.;
goto apply_adj;
}
}
else if (!dsign) {
adj = -1.;
if (!word1(rv)
&& !(word0(rv) & Frac_mask)) {
y = word0(rv) & Exp_mask;
#ifdef Avoid_Underflow
if (!scale || y > 2*P*Exp_msk1)
#else
if (y)
#endif
{
delta = lshift(delta,Log2P);
if (cmp(delta, bs) <= 0)
adj = -0.5;
}
}
apply_adj:
#ifdef Avoid_Underflow
if (scale && (y = word0(rv) & Exp_mask)
<= 2*P*Exp_msk1)
word0(adj) += (2*P+1)*Exp_msk1 - y;
#else
#ifdef Sudden_Underflow
if ((word0(rv) & Exp_mask) <=
P*Exp_msk1) {
word0(rv) += P*Exp_msk1;
dval(rv) += adj*ulp(dval(rv));
word0(rv) -= P*Exp_msk1;
}
else
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
dval(rv) += adj*ulp(dval(rv));
}
break;
}
adj = ratio(delta, bs);
if (adj < 1.)
adj = 1.;
if (adj <= 0x7ffffffe) {
/* adj = rounding ? ceil(adj) : floor(adj); */
y = adj;
if (y != adj) {
if (!((rounding>>1) ^ dsign))
y++;
adj = y;
}
}
#ifdef Avoid_Underflow
if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
word0(adj) += (2*P+1)*Exp_msk1 - y;
#else
#ifdef Sudden_Underflow
if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
word0(rv) += P*Exp_msk1;
adj *= ulp(dval(rv));
if (dsign)
dval(rv) += adj;
else
dval(rv) -= adj;
word0(rv) -= P*Exp_msk1;
goto cont;
}
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
adj *= ulp(dval(rv));
if (dsign)
dval(rv) += adj;
else
dval(rv) -= adj;
goto cont;
}
#endif /*Honor_FLT_ROUNDS*/
if (i < 0) {
/* Error is less than half an ulp -- check for
* special case of mantissa a power of two.
*/
if (dsign || word1(rv) || word0(rv) & Bndry_mask
#ifdef IEEE_Arith
#ifdef Avoid_Underflow
|| (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
#else
|| (word0(rv) & Exp_mask) <= Exp_msk1
#endif
#endif
) {
#ifdef SET_INEXACT
if (!delta->x[0] && delta->wds <= 1)
inexact = 0;
#endif
break;
}
if (!delta->x[0] && delta->wds <= 1) {
/* exact result */
#ifdef SET_INEXACT
inexact = 0;
#endif
break;
}
delta = lshift(delta,Log2P);
if (cmp(delta, bs) > 0)
goto drop_down;
break;
}
if (i == 0) {
/* exactly half-way between */
if (dsign) {
if ((word0(rv) & Bndry_mask1) == Bndry_mask1
&& word1(rv) == (
#ifdef Avoid_Underflow
(scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
#endif
0xffffffff)) {
/*boundary case -- increment exponent*/
word0(rv) = (word0(rv) & Exp_mask)
+ Exp_msk1
#ifdef IBM
| Exp_msk1 >> 4
#endif
;
word1(rv) = 0;
#ifdef Avoid_Underflow
dsign = 0;
#endif
break;
}
}
else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
drop_down:
/* boundary case -- decrement exponent */
#ifdef Sudden_Underflow /*{{*/
L = word0(rv) & Exp_mask;
#ifdef IBM
if (L < Exp_msk1)
#else
#ifdef Avoid_Underflow
if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
#else
if (L <= Exp_msk1)
#endif /*Avoid_Underflow*/
#endif /*IBM*/
goto undfl;
L -= Exp_msk1;
#else /*Sudden_Underflow}{*/
#ifdef Avoid_Underflow
if (scale) {
L = word0(rv) & Exp_mask;
if (L <= (2*P+1)*Exp_msk1) {
if (L > (P+2)*Exp_msk1)
/* round even ==> */
/* accept rv */
break;
/* rv = smallest denormal */
goto undfl;
}
}
#endif /*Avoid_Underflow*/
L = (word0(rv) & Exp_mask) - Exp_msk1;
#endif /*Sudden_Underflow}*/
word0(rv) = L | Bndry_mask1;
word1(rv) = 0xffffffff;
#ifdef IBM
goto cont;
#else
break;
#endif
}
#ifndef ROUND_BIASED
if (!(word1(rv) & LSB))
break;
#endif
if (dsign)
dval(rv) += ulp(dval(rv));
#ifndef ROUND_BIASED
else {
dval(rv) -= ulp(dval(rv));
#ifndef Sudden_Underflow
if (!dval(rv))
goto undfl;
#endif
}
#ifdef Avoid_Underflow
dsign = 1 - dsign;
#endif
#endif
break;
}
if ((aadj = ratio(delta, bs)) <= 2.) {
if (dsign)
aadj = aadj1 = 1.;
else if (word1(rv) || word0(rv) & Bndry_mask) {
#ifndef Sudden_Underflow
if (word1(rv) == Tiny1 && !word0(rv))
goto undfl;
#endif
aadj = 1.;
aadj1 = -1.;
}
else {
/* special case -- power of FLT_RADIX to be */
/* rounded down... */
if (aadj < 2./FLT_RADIX)
aadj = 1./FLT_RADIX;
else
aadj *= 0.5;
aadj1 = -aadj;
}
}
else {
aadj *= 0.5;
aadj1 = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS
switch(Rounding) {
case 2: /* towards +infinity */
aadj1 -= 0.5;
break;
case 0: /* towards 0 */
case 3: /* towards -infinity */
aadj1 += 0.5;
}
#else
if (Flt_Rounds == 0)
aadj1 += 0.5;
#endif /*Check_FLT_ROUNDS*/
}
y = word0(rv) & Exp_mask;
/* Check for overflow */
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
dval(rv0) = dval(rv);
word0(rv) -= P*Exp_msk1;
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
if ((word0(rv) & Exp_mask) >=
Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
if (word0(rv0) == Big0 && word1(rv0) == Big1)
goto ovfl;
word0(rv) = Big0;
word1(rv) = Big1;
goto cont;
}
else
word0(rv) += P*Exp_msk1;
}
else {
#ifdef Avoid_Underflow
if (scale && y <= 2*P*Exp_msk1) {
if (aadj <= 0x7fffffff) {
if ((z = aadj) <= 0)
z = 1;
aadj = z;
aadj1 = dsign ? aadj : -aadj;
}
word0(aadj1) += (2*P+1)*Exp_msk1 - y;
}
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
#else
#ifdef Sudden_Underflow
if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
dval(rv0) = dval(rv);
word0(rv) += P*Exp_msk1;
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
#ifdef IBM
if ((word0(rv) & Exp_mask) < P*Exp_msk1)
#else
if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
#endif
{
if (word0(rv0) == Tiny0
&& word1(rv0) == Tiny1)
goto undfl;
word0(rv) = Tiny0;
word1(rv) = Tiny1;
goto cont;
}
else
word0(rv) -= P*Exp_msk1;
}
else {
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
}
#else /*Sudden_Underflow*/
/* Compute adj so that the IEEE rounding rules will
* correctly round rv + adj in some half-way cases.
* If rv * ulp(rv) is denormalized (i.e.,
* y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
* trouble from bits lost to denormalization;
* example: 1.2e-307 .
*/
if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
aadj1 = (double)(int)(aadj + 0.5);
if (!dsign)
aadj1 = -aadj1;
}
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
}
z = word0(rv) & Exp_mask;
#ifndef SET_INEXACT
#ifdef Avoid_Underflow
if (!scale)
#endif
if (y == z) {
/* Can we stop now? */
L = (Long)aadj;
aadj -= L;
/* The tolerances below are conservative. */
if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
if (aadj < .4999999 || aadj > .5000001)
break;
}
else if (aadj < .4999999/FLT_RADIX)
break;
}
#endif
cont:
Bfree(bb);
Bfree(bd);
Bfree(bs);
Bfree(delta);
}
#ifdef SET_INEXACT
if (inexact) {
if (!oldinexact) {
word0(rv0) = Exp_1 + (70 << Exp_shift);
word1(rv0) = 0;
dval(rv0) += 1.;
}
}
else if (!oldinexact)
clear_inexact();
#endif
#ifdef Avoid_Underflow
if (scale) {
word0(rv0) = Exp_1 - 2*P*Exp_msk1;
word1(rv0) = 0;
dval(rv) *= dval(rv0);
#ifndef NO_ERRNO
/* try to avoid the bug of testing an 8087 register value */
if (word0(rv) == 0 && word1(rv) == 0)
errno = ERANGE;
#endif
}
#endif /* Avoid_Underflow */
#ifdef SET_INEXACT
if (inexact && !(word0(rv) & Exp_mask)) {
/* set underflow bit */
dval(rv0) = 1e-300;
dval(rv0) *= dval(rv0);
}
#endif
retfree:
Bfree(bb);
Bfree(bd);
Bfree(bs);
Bfree(bd0);
Bfree(delta);
ret:
if (se)
*se = (char *)s;
return sign ? -dval(rv) : dval(rv);
}

177
contrib/gdtoa/strtodI.c Normal file
View File

@ -0,0 +1,177 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
static double
#ifdef KR_headers
ulpdown(d) double *d;
#else
ulpdown(double *d)
#endif
{
double u;
ULong *L = (ULong*)d;
u = ulp(*d);
if (!(L[_1] | L[_0] & 0xfffff)
&& (L[_0] & 0x7ff00000) > 0x00100000)
u *= 0.5;
return u;
}
int
#ifdef KR_headers
strtodI(s, sp, dd) CONST char *s; char **sp; double *dd;
#else
strtodI(CONST char *s, char **sp, double *dd)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 1 };
#else
static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
#endif
ULong bits[2], sign;
Long exp;
int j, k;
typedef union {
double d[2];
ULong L[4];
} U;
U *u;
k = strtodg(s, sp, &fpi, &exp, bits);
u = (U*)dd;
sign = k & STRTOG_Neg ? 0x80000000L : 0;
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
u->d[0] = u->d[1] = 0.;
break;
case STRTOG_Zero:
u->d[0] = u->d[1] = 0.;
#ifdef Sudden_Underflow
if (k & STRTOG_Inexact) {
if (sign)
u->L[_0] = 0x80100000L;
else
u->L[2+_0] = 0x100000L;
}
break;
#else
goto contain;
#endif
case STRTOG_Denormal:
u->L[_1] = bits[0];
u->L[_0] = bits[1];
goto contain;
case STRTOG_Normal:
u->L[_1] = bits[0];
u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
contain:
j = k & STRTOG_Inexact;
if (sign) {
u->L[_0] |= sign;
j = STRTOG_Inexact - j;
}
switch(j) {
case STRTOG_Inexlo:
#ifdef Sudden_Underflow
if ((u->L[_0] & 0x7ff00000) < 0x3500000) {
u->L[2+_0] = u->L[_0] + 0x3500000;
u->L[2+_1] = u->L[_1];
u->d[1] += ulp(u->d[1]);
u->L[2+_0] -= 0x3500000;
if (!(u->L[2+_0] & 0x7ff00000)) {
u->L[2+_0] = sign;
u->L[2+_1] = 0;
}
}
else
#endif
u->d[1] = u->d[0] + ulp(u->d[0]);
break;
case STRTOG_Inexhi:
u->d[1] = u->d[0];
#ifdef Sudden_Underflow
if ((u->L[_0] & 0x7ff00000) < 0x3500000) {
u->L[_0] += 0x3500000;
u->d[0] -= ulpdown(u->d);
u->L[_0] -= 0x3500000;
if (!(u->L[_0] & 0x7ff00000)) {
u->L[_0] = sign;
u->L[_1] = 0;
}
}
else
#endif
u->d[0] -= ulpdown(u->d);
break;
default:
u->d[1] = u->d[0];
}
break;
case STRTOG_Infinite:
u->L[_0] = u->L[2+_0] = sign | 0x7ff00000;
u->L[_1] = u->L[2+_1] = 0;
if (k & STRTOG_Inexact) {
if (sign) {
u->L[2+_0] = 0xffefffffL;
u->L[2+_1] = 0xffffffffL;
}
else {
u->L[_0] = 0x7fefffffL;
u->L[_1] = 0xffffffffL;
}
}
break;
case STRTOG_NaN:
u->L[_0] = u->L[2+_0] = 0x7fffffff | sign;
u->L[_1] = u->L[2+_1] = (ULong)-1;
break;
case STRTOG_NaNbits:
u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1];
u->L[_1] = u->L[2+_1] = bits[0];
}
return k;
}

1022
contrib/gdtoa/strtodg.c Normal file

File diff suppressed because it is too large Load Diff

83
contrib/gdtoa/strtof.c Normal file
View File

@ -0,0 +1,83 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
float
#ifdef KR_headers
strtof(s, sp) CONST char *s; char **sp;
#else
strtof(CONST char *s, char **sp)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 1 };
#else
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
#endif
ULong bits[1];
Long exp;
int k;
union { ULong L[1]; float f; } u;
k = strtodg(s, sp, &fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
u.L[0] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
break;
case STRTOG_Denormal:
u.L[0] = bits[0];
break;
case STRTOG_Infinite:
u.L[0] = 0x7f800000;
break;
case STRTOG_NaN:
u.L[0] = 0x7fffffff;
}
if (k & STRTOG_Neg)
u.L[0] |= 0x80000000L;
return u.f;
}

109
contrib/gdtoa/strtopQ.c Normal file
View File

@ -0,0 +1,109 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
int
#ifdef KR_headers
strtopQ(s, sp, V) CONST char *s; char **sp; void *V;
#else
strtopQ(CONST char *s, char **sp, void *V)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 1 };
#else
static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
#endif
ULong bits[4];
Long exp;
int k;
ULong *L = (ULong*)V;
k = strtodg(s, sp, &fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
break;
case STRTOG_Denormal:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = bits[3];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff0000;
L[_1] = L[_2] = L[_3] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fffffff;
L[_1] = L[_2] = L[_3] = (ULong)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
return k;
}

55
contrib/gdtoa/strtopd.c Normal file
View File

@ -0,0 +1,55 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtopd(s, sp, d) char *s; char **sp; double *d;
#else
strtopd(CONST char *s, char **sp, double *d)
#endif
{
static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
ULong bits[2];
Long exp;
int k;
k = strtodg(s, sp, &fpi0, &exp, bits);
ULtod((ULong*)d, bits, exp, k);
return k;
}

184
contrib/gdtoa/strtopdd.c Normal file
View File

@ -0,0 +1,184 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd;
#else
strtopdd(CONST char *s, char **sp, double *dd)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
#else
static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
#endif
ULong bits[4];
Long exp;
int i, j, rv;
typedef union {
double d[2];
ULong L[4];
} U;
U *u;
rv = strtodg(s, sp, &fpi, &exp, bits);
u = (U*)dd;
switch(rv & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
u->d[0] = u->d[1] = 0.;
break;
case STRTOG_Normal:
u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL;
u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff
| exp + 0x3ff + 105 << 20;
exp += 0x3ff + 52;
if (bits[1] &= 0x1fffff) {
i = hi0bits(bits[1]) - 11;
if (i >= exp) {
i = exp - 1;
exp = 0;
}
else
exp -= i;
if (i > 0) {
bits[1] = bits[1] << i | bits[0] >> 32-i;
bits[0] = bits[0] << i & 0xffffffffL;
}
}
else if (bits[0]) {
i = hi0bits(bits[0]) + 21;
if (i >= exp) {
i = exp - 1;
exp = 0;
}
else
exp -= i;
if (i < 32) {
bits[1] = bits[0] >> 32 - i;
bits[0] = bits[0] << i & 0xffffffffL;
}
else {
bits[1] = bits[0] << i - 32;
bits[0] = 0;
}
}
else {
u->L[2] = u->L[3] = 0;
break;
}
u->L[2+_1] = bits[0];
u->L[2+_0] = bits[1] & 0xfffff | exp << 20;
break;
case STRTOG_Denormal:
if (bits[3])
goto nearly_normal;
if (bits[2])
goto partly_normal;
if (bits[1] & 0xffe00000)
goto hardly_normal;
/* completely denormal */
u->L[2] = u->L[3] = 0;
u->L[_1] = bits[0];
u->L[_0] = bits[1];
break;
nearly_normal:
i = hi0bits(bits[3]) - 11; /* i >= 12 */
j = 32 - i;
u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff
| 65 - i << 20;
u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
u->L[2+_0] = bits[1] & (1L << j) - 1;
u->L[2+_1] = bits[0];
break;
partly_normal:
i = hi0bits(bits[2]) - 11;
if (i < 0) {
j = -i;
i += 32;
u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20;
u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
u->L[2+_0] = bits[1] & (1L << j) - 1;
u->L[2+_1] = bits[0];
break;
}
if (i == 0) {
u->L[_0] = bits[2] & 0xfffff | 33 << 20;
u->L[_1] = bits[1];
u->L[2+_0] = 0;
u->L[2+_1] = bits[0];
break;
}
j = 32 - i;
u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff
| j + 1 << 20;
u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
u->L[2+_0] = 0;
u->L[2+_1] = bits[0] & (1L << j) - 1;
break;
hardly_normal:
j = 11 - hi0bits(bits[1]);
i = 32 - j;
u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20;
u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
u->L[2+_0] = 0;
u->L[2+_1] = bits[0] & (1L << j) - 1;
break;
case STRTOG_Infinite:
u->L[_0] = u->L[2+_0] = 0x7ff00000;
u->L[_1] = u->L[2+_1] = 0;
break;
case STRTOG_NaN:
u->L[_0] = u->L[2+_0] = 0x7fffffff;
u->L[_1] = u->L[2+_1] = (ULong)-1;
}
if (rv & STRTOG_Neg) {
u->L[ _0] |= 0x80000000L;
u->L[2+_0] |= 0x80000000L;
}
return rv;
}

83
contrib/gdtoa/strtopf.c Normal file
View File

@ -0,0 +1,83 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
int
#ifdef KR_headers
strtopf(s, sp, f) CONST char *s; char **sp; float *f;
#else
strtopf(CONST char *s, char **sp, float *f)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 1 };
#else
static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 };
#endif
ULong bits[1], *L;
Long exp;
int k;
k = strtodg(s, sp, &fpi, &exp, bits);
L = (ULong*)f;
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
break;
case STRTOG_Denormal:
L[0] = bits[0];
break;
case STRTOG_Infinite:
L[0] = 0x7f800000;
break;
case STRTOG_NaN:
L[0] = 0x7fffffff;
}
if (k & STRTOG_Neg)
L[0] |= 0x80000000L;
return k;
}

106
contrib/gdtoa/strtopx.c Normal file
View File

@ -0,0 +1,106 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
int
#ifdef KR_headers
strtopx(s, sp, V) CONST char *s; char **sp; void *V;
#else
strtopx(CONST char *s, char **sp, void *V)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 1 };
#else
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
#endif
ULong bits[2];
Long exp;
int k;
UShort *L = (UShort*)V;
k = strtodg(s, sp, &fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = L[4] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_4] = (UShort)bits[0];
L[_3] = (UShort)(bits[0] >> 16);
L[_2] = (UShort)bits[1];
L[_1] = (UShort)(bits[1] >> 16);
L[_0] = exp + 0x3fff + 63;
break;
case STRTOG_Infinite:
L[_0] = 0x7fff;
L[_1] = L[_2] = L[_3] = L[_4] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fff;
L[_1] = L[_2] = L[_3] = L[_4] = (UShort)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;
return k;
}

100
contrib/gdtoa/strtopxL.c Normal file
View File

@ -0,0 +1,100 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
int
#ifdef KR_headers
strtopxL(s, sp, V) CONST char *s; char **sp; void *V;
#else
strtopxL(CONST char *s, char **sp, void *V)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 1 };
#else
static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
#endif
ULong bits[2];
Long exp;
int k;
ULong *L = (ULong*)V;
k = strtodg(s, sp, &fpi, &exp, bits);
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_2] = bits[0];
L[_1] = bits[1];
L[_0] = (exp + 0x3fff + 63) << 16;
break;
case STRTOG_Infinite:
L[_0] = 0x7fff << 16;
L[_1] = L[_2] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fff << 16;
L[_1] = L[_2] = (ULong)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
return k;
}

121
contrib/gdtoa/strtorQ.c Normal file
View File

@ -0,0 +1,121 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
void
#ifdef KR_headers
ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtoQ(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16);
break;
case STRTOG_Denormal:
L[_3] = bits[0];
L[_2] = bits[1];
L[_1] = bits[2];
L[_0] = bits[3];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff0000;
L[_1] = L[_2] = L[_3] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fffffff;
L[_1] = L[_2] = L[_3] = (ULong)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
strtorQ(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI };
FPI *fpi, fpi1;
ULong bits[4];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtoQ((ULong*)L, bits, exp, k);
return k;
}

99
contrib/gdtoa/strtord.c Normal file
View File

@ -0,0 +1,99 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
void
#ifdef KR_headers
ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtod(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = 0;
break;
case STRTOG_Denormal:
L[_1] = bits[0];
L[_0] = bits[1];
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[_1] = bits[0];
L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
break;
case STRTOG_Infinite:
L[_0] = 0x7ff00000;
L[_1] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fffffff;
L[_1] = (ULong)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d;
#else
strtord(CONST char *s, char **sp, int rounding, double *d)
#endif
{
static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
FPI *fpi, fpi1;
ULong bits[2];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtod((ULong*)d, bits, exp, k);
return k;
}

205
contrib/gdtoa/strtordd.c Normal file
View File

@ -0,0 +1,205 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
void
#ifdef KR_headers
ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtodd(ULong *L, ULong *bits, Long exp, int k)
#endif
{
int i, j;
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = 0;
break;
case STRTOG_Normal:
L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff
| exp + 0x3ff + 105 << 20;
exp += 0x3ff + 52;
if (bits[1] &= 0x1fffff) {
i = hi0bits(bits[1]) - 11;
if (i >= exp) {
i = exp - 1;
exp = 0;
}
else
exp -= i;
if (i > 0) {
bits[1] = bits[1] << i | bits[0] >> 32-i;
bits[0] = bits[0] << i & (ULong)0xffffffffL;
}
}
else if (bits[0]) {
i = hi0bits(bits[0]) + 21;
if (i >= exp) {
i = exp - 1;
exp = 0;
}
else
exp -= i;
if (i < 32) {
bits[1] = bits[0] >> 32 - i;
bits[0] = bits[0] << i & (ULong)0xffffffffL;
}
else {
bits[1] = bits[0] << i - 32;
bits[0] = 0;
}
}
else {
L[2] = L[3] = 0;
break;
}
L[2+_1] = bits[0];
L[2+_0] = bits[1] & 0xfffff | exp << 20;
break;
case STRTOG_Denormal:
if (bits[3])
goto nearly_normal;
if (bits[2])
goto partly_normal;
if (bits[1] & 0xffe00000)
goto hardly_normal;
/* completely denormal */
L[2] = L[3] = 0;
L[_1] = bits[0];
L[_0] = bits[1];
break;
nearly_normal:
i = hi0bits(bits[3]) - 11; /* i >= 12 */
j = 32 - i;
L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff
| 65 - i << 20;
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
L[2+_0] = bits[1] & ((ULong)1L << j) - 1;
L[2+_1] = bits[0];
break;
partly_normal:
i = hi0bits(bits[2]) - 11;
if (i < 0) {
j = -i;
i += 32;
L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20;
L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL;
L[2+_0] = bits[1] & ((ULong)1L << j) - 1;
L[2+_1] = bits[0];
break;
}
if (i == 0) {
L[_0] = bits[2] & 0xfffff | 33 << 20;
L[_1] = bits[1];
L[2+_0] = 0;
L[2+_1] = bits[0];
break;
}
j = 32 - i;
L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff
| j + 1 << 20;
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
L[2+_0] = 0;
L[2+_1] = bits[0] & (1L << j) - 1;
break;
hardly_normal:
j = 11 - hi0bits(bits[1]);
i = 32 - j;
L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20;
L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL;
L[2+_0] = 0;
L[2+_1] = bits[0] & ((ULong)1L << j) - 1;
break;
case STRTOG_Infinite:
L[_0] = L[2+_0] = 0x7ff00000;
L[_1] = L[2+_1] = 0;
break;
case STRTOG_NaN:
L[_0] = L[2+_0] = 0x7fffffff;
L[_1] = L[2+_1] = (ULong)-1;
break;
case STRTOG_NaNbits:
L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL;
L[_0] = bits[2] >> 21 | bits[3] << 11
| (ULong)0x7ff00000L;
L[2+_1] = bits[0];
L[2+_0] = bits[1] | (ULong)0x7ff00000L;
}
if (k & STRTOG_Neg) {
L[_0] |= 0x80000000L;
L[2+_0] |= 0x80000000L;
}
}
int
#ifdef KR_headers
strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd;
#else
strtordd(CONST char *s, char **sp, int rounding, double *dd)
#endif
{
#ifdef Sudden_Underflow
static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
#else
static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
#endif
FPI *fpi, fpi1;
ULong bits[4];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtodd((ULong*)dd, bits, exp, k);
return k;
}

95
contrib/gdtoa/strtorf.c Normal file
View File

@ -0,0 +1,95 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
void
#ifdef KR_headers
ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtof(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
*L = 0;
break;
case STRTOG_Normal:
case STRTOG_NaNbits:
L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
break;
case STRTOG_Denormal:
L[0] = bits[0];
break;
case STRTOG_Infinite:
L[0] = 0x7f800000;
break;
case STRTOG_NaN:
L[0] = 0x7fffffff;
}
if (k & STRTOG_Neg)
L[0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f;
#else
strtorf(CONST char *s, char **sp, int rounding, float *f)
#endif
{
static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
FPI *fpi, fpi1;
ULong bits[1];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtof((ULong*)f, bits, exp, k);
return k;
}

118
contrib/gdtoa/strtorx.c Normal file
View File

@ -0,0 +1,118 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
void
#ifdef KR_headers
ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k;
#else
ULtox(UShort *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = L[3] = L[4] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_4] = (UShort)bits[0];
L[_3] = (UShort)(bits[0] >> 16);
L[_2] = (UShort)bits[1];
L[_1] = (UShort)(bits[1] >> 16);
L[_0] = exp + 0x3fff + 63;
break;
case STRTOG_Infinite:
L[_0] = 0x7fff;
L[_1] = L[_2] = L[_3] = L[_4] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fff;
L[_1] = L[_2] = L[_3] = L[_4] = (UShort)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x8000;
}
int
#ifdef KR_headers
strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
strtorx(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
FPI *fpi, fpi1;
ULong bits[2];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtox((UShort*)L, bits, exp, k);
return k;
}

112
contrib/gdtoa/strtorxL.c Normal file
View File

@ -0,0 +1,112 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2000 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
void
#ifdef KR_headers
ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k;
#else
ULtoxL(ULong *L, ULong *bits, Long exp, int k)
#endif
{
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
case STRTOG_Zero:
L[0] = L[1] = L[2] = 0;
break;
case STRTOG_Normal:
case STRTOG_Denormal:
case STRTOG_NaNbits:
L[_0] = (exp + 0x3fff + 63) << 16;
L[_1] = bits[1];
L[_2] = bits[0];
break;
case STRTOG_Infinite:
L[_0] = 0x7fff << 16;
L[_1] = L[_2] = 0;
break;
case STRTOG_NaN:
L[_0] = 0x7fff << 16;
L[_1] = L[_2] = (ULong)-1;
}
if (k & STRTOG_Neg)
L[_0] |= 0x80000000L;
}
int
#ifdef KR_headers
strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L;
#else
strtorxL(CONST char *s, char **sp, int rounding, void *L)
#endif
{
static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI };
FPI *fpi, fpi1;
ULong bits[2];
Long exp;
int k;
fpi = &fpi0;
if (rounding != FPI_Round_near) {
fpi1 = fpi0;
fpi1.rounding = rounding;
fpi = &fpi1;
}
k = strtodg(s, sp, fpi, &exp, bits);
ULtoxL((ULong*)L, bits, exp, k);
return k;
}

104
contrib/gdtoa/sum.c Normal file
View File

@ -0,0 +1,104 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
Bigint *
#ifdef KR_headers
sum(a, b) Bigint *a; Bigint *b;
#else
sum(Bigint *a, Bigint *b)
#endif
{
Bigint *c;
ULong carry, *xc, *xa, *xb, *xe, y;
#ifdef Pack_32
ULong z;
#endif
if (a->wds < b->wds) {
c = b; b = a; a = c;
}
c = Balloc(a->k);
c->wds = a->wds;
carry = 0;
xa = a->x;
xb = b->x;
xc = c->x;
xe = xc + b->wds;
#ifdef Pack_32
do {
y = (*xa & 0xffff) + (*xb & 0xffff) + carry;
carry = (y & 0x10000) >> 16;
z = (*xa++ >> 16) + (*xb++ >> 16) + carry;
carry = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
}
while(xc < xe);
xe += a->wds - b->wds;
while(xc < xe) {
y = (*xa & 0xffff) + carry;
carry = (y & 0x10000) >> 16;
z = (*xa++ >> 16) + carry;
carry = (z & 0x10000) >> 16;
Storeinc(xc, z, y);
}
#else
do {
y = *xa++ + *xb++ + carry;
carry = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
while(xc < xe);
xe += a->wds - b->wds;
while(xc < xe) {
y = *xa++ + carry;
carry = (y & 0x10000) >> 16;
*xc++ = y & 0xffff;
}
#endif
if (carry) {
if (c->wds == c->maxwds) {
b = Balloc(c->k + 1);
Bcopy(b, c);
Bfree(c);
c = b;
}
c->x[c->wds++] = 1;
}
return c;
}

1180
contrib/gdtoa/test/Q.ou0 Normal file

File diff suppressed because it is too large Load Diff

1468
contrib/gdtoa/test/Q.ou1 Normal file

File diff suppressed because it is too large Load Diff

170
contrib/gdtoa/test/Qtest.c Normal file
View File

@ -0,0 +1,170 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_Qfmt, strtoIQ, strtopQ, and strtorQ.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex0 hex1 hex2 hex3
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex0 is a string of <= 8 Hex digits for the most significant
* word of the number, hex1 is a similar string for the next
* word, etc., and ndig is a parameters to g_Qfmt.
*/
#include "gdtoa.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[2048];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#endif
#ifdef IEEE_8087
#define _0 3
#define _1 2
#define _2 1
#define _3 0
#endif
#define U (unsigned long)
int
main(Void)
{
char *s, *se, *se1;
int i, dItry, ndig = 0, r = 1;
union { long double d; ULong bits[4]; } u, v[2];
while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
while(*s <= ' ')
if (!*s++)
continue;
dItry = 0;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
sscanf(s+1, "%lx %lx %lx %lx", &u.bits[_0],
&u.bits[_1], &u.bits[_2], &u.bits[_3]);
printf("\nInput: %s", ibuf);
printf(" --> f = #%lx %lx %lx %lx\n", u.bits[_0],
u.bits[_1], u.bits[_2], u.bits[_3]);
goto fmt_test;
}
dItry = 1;
printf("\nInput: %s", ibuf);
i = strtorQ(ibuf, &se, r, u.bits);
if (r == 1 && (strtopQ(ibuf,&se1,v[0].bits) != i
|| se != se1 || memcmp(u.bits, v[0].bits, 16)))
printf("***strtoQ and strtorQ disagree!!\n:");
printf("\nstrtoQ consumes %d bytes and returns %d\n",
(int)(se-ibuf), i);
printf("with bits = #%lx %lx %lx %lx\n",
U u.bits[_0], U u.bits[_1], U u.bits[_2], U u.bits[_3]);
fmt_test:
if (sizeof(long double) == 16)
printf("printf(\"%%.35Lg\") gives %.35Lg\n", u.d);
se = g_Qfmt(obuf, u.bits, ndig, sizeof(obuf));
printf("g_Qfmt(%d) gives %d bytes: \"%s\"\n\n", ndig,
(int)(se-obuf), se ? obuf : "<null>");
if (!dItry)
continue;
printf("strtoIQ returns %d,",
strtoIQ(ibuf, &se, v[0].bits, v[1].bits));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (!memcmp(v[0].bits, v[1].bits, 16)) {
if (!memcpy(u.bits, v[0].bits, 16))
printf("fI[0] == fI[1] == strtoQ\n");
else {
printf("fI[0] == fI[1] = #%lx %lx %lx %lx\n",
U v[0].bits[_0], U v[0].bits[_1],
U v[0].bits[_2], U v[0].bits[_3]);
if (sizeof(long double) == 16)
printf("= %.35Lg\n", v[0].d);
}
}
else {
printf("fI[0] = #%lx %lx %lx %lx\n",
U v[0].bits[_0], U v[0].bits[_1],
U v[0].bits[_2], U v[0].bits[_3]);
if (sizeof(long double) == 16)
printf("= %.35Lg\n", v[0].d);
printf("fI[1] = #%lx %lx %lx %lx\n",
U v[1].bits[_0], U v[1].bits[_1],
U v[1].bits[_2], U v[1].bits[_3]);
if (sizeof(long double) == 16)
printf("= %.35Lg\n", v[1].d);
if (!memcmp(v[0].bits, u.bits, 16))
printf("fI[0] == strtod\n");
else if (!memcmp(v[1].bits, u.bits, 16))
printf("fI[1] == strtod\n");
else
printf("**** Both differ from strtod ****\n");
}
printf("\n");
}
return 0;
}

61
contrib/gdtoa/test/README Normal file
View File

@ -0,0 +1,61 @@
This directory contains source for several test programs:
dt is for conversion to/from double; it permits input of pairs of
32-bit hex integers as #hhhhhhhh hhhhhhhh (i.e., the initial '#'
indicates hex input). No initial # ==> decimal input.
After the input number is an optional : mode ndigits
(colon, and decimal integers for parameters "mode" and "ndigits"
to gdtoa).
Qtest, ddtest, dtest, ftest, xLtest and xtest are for conversion to/from
f IEEE single precision
d IEEE double precision
xL IEEE extended precision, as on Motorola 680x0 chips
x IEEE extended precision, as on Intel 80x87 chips or
software emulation of Motorola 680x0 chips
Q quad precision, as on Sun Sparc chips
dd double double, pairs of IEEE double numbers
whose sum is the desired value
They're all similar, except for the precision. They test both
directed roundings and interval input (the strtoI* routines).
Lines that begin with "r" specify or interrogate the desired rounding
direction:
0 = toward 0
1 = nearest (default)
2 = toward +Infinity
3 = toward -Infinity
These are the FPI_Round_* values in gdota.h. The "r" value is sticky:
it stays in effect til changed. To change the value, give a line that
starts with r followed by 0, 1, 2, or 3. To check the value, give "r"
by itself.
Lines that begin with n followed by a number specify the ndig
argument for subsequent calls to the relevant g_*fmt routine.
Lines that start with # followed by the appropriate number of
hexadecimal strings (see the comments) give the big-endian
internal representation of the desired number.
When routines Qtest, xLtest, and xtest are used on machines whose
long double is of type "quad" (for Qtest) or "extended" (for x*test),
they try to print with %Lg as another way to show binary values.
Program ddtest also accepts (white-space separated) pairs of decimal
input numbers; it converts both with strtod and feeds the result
to g_ddfmt.
Program dItest exercises strtodI and strtoId.
Programs dItestsi and ddtestsi are for testing the sudden-underflow
logic (on double and double-double conversions).
Program strtodt tests strtod on some hard cases (in file testnos3)
posted by Fred Tydeman to comp.arch.arithmetic on 26 Feb. 1996.
These are simple test programs, not meant for exhaustive testing,
but for manually testing "interesting" cases. Paxson's testbase
is good for more exhaustive testing, in part with random inputs.

986
contrib/gdtoa/test/d.out Normal file
View File

@ -0,0 +1,986 @@
Input: 1.23
strtod consumes 4 bytes and returns 17 with f = 1.23 = #3ff3ae14 7ae147ae
g_dfmt(0) gives 4 bytes: "1.23"
strtoId returns 17, consuming 4 bytes.
fI[0] = #3ff3ae14 7ae147ae = 1.23
fI[1] = #3ff3ae14 7ae147af = 1.2300000000000002
fI[0] == strtod
Input: 1.23e+20
strtod consumes 8 bytes and returns 1 with f = 1.23e+20 = #441aabdf 2145b430
g_dfmt(0) gives 8 bytes: "1.23e+20"
strtoId returns 1, consuming 8 bytes.
fI[0] == fI[1] == strtod
Input: 1.23e-20
strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-20 = #3bcd0ae4 cf767531
g_dfmt(0) gives 8 bytes: "1.23e-20"
strtoId returns 33, consuming 8 bytes.
fI[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
fI[1] = #3bcd0ae4 cf767531 = 1.2300000000000001e-20
fI[1] == strtod
Input: 1.23456789
strtod consumes 10 bytes and returns 17 with f = 1.2345678899999999 = #3ff3c0ca 4283de1b
g_dfmt(0) gives 10 bytes: "1.23456789"
strtoId returns 17, consuming 10 bytes.
fI[0] = #3ff3c0ca 4283de1b = 1.2345678899999999
fI[1] = #3ff3c0ca 4283de1c = 1.2345678900000001
fI[0] == strtod
Input: 1.23456589e+20
strtod consumes 14 bytes and returns 17 with f = 1.23456589e+20 = #441ac537 a660b997
g_dfmt(0) gives 14 bytes: "1.23456589e+20"
strtoId returns 17, consuming 14 bytes.
fI[0] = #441ac537 a660b997 = 1.23456589e+20
fI[1] = #441ac537 a660b998 = 1.2345658900000001e+20
fI[0] == strtod
Input: 1.23e+30
strtod consumes 8 bytes and returns 17 with f = 1.23e+30 = #462f0cb0 4e8fb790
g_dfmt(0) gives 8 bytes: "1.23e+30"
strtoId returns 17, consuming 8 bytes.
fI[0] = #462f0cb0 4e8fb790 = 1.23e+30
fI[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30
fI[0] == strtod
Input: 1.23e-30
strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-30 = #39b8f286 6f5010ab
g_dfmt(0) gives 8 bytes: "1.23e-30"
strtoId returns 33, consuming 8 bytes.
fI[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30
fI[1] = #39b8f286 6f5010ab = 1.2300000000000001e-30
fI[1] == strtod
Input: 1.23456789e-20
strtod consumes 14 bytes and returns 17 with f = 1.2345678899999999e-20 = #3bcd2681 471e7ada
g_dfmt(0) gives 14 bytes: "1.23456789e-20"
strtoId returns 17, consuming 14 bytes.
fI[0] = #3bcd2681 471e7ada = 1.2345678899999999e-20
fI[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20
fI[0] == strtod
Input: 1.23456789e-30
strtod consumes 14 bytes and returns 17 with f = 1.23456789e-30 = #39b90a3e 33bbd995
g_dfmt(0) gives 14 bytes: "1.23456789e-30"
strtoId returns 17, consuming 14 bytes.
fI[0] = #39b90a3e 33bbd995 = 1.23456789e-30
fI[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30
fI[0] == strtod
Input: 1.234567890123456789
strtod consumes 20 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb
g_dfmt(0) gives 18 bytes: "1.2345678901234567"
strtoId returns 17, consuming 20 bytes.
fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569
fI[0] == strtod
Input: 1.23456789012345678901234567890123456789
strtod consumes 40 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb
g_dfmt(0) gives 18 bytes: "1.2345678901234567"
strtoId returns 17, consuming 40 bytes.
fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569
fI[0] == strtod
Input: 1.23e306
strtod consumes 8 bytes and returns 33 with f = 1.23e+306 = #7f7c0676 cd1c61f5
g_dfmt(0) gives 9 bytes: "1.23e+306"
strtoId returns 33, consuming 8 bytes.
fI[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306
fI[1] = #7f7c0676 cd1c61f5 = 1.23e+306
fI[1] == strtod
Input: 1.23e-306
strtod consumes 9 bytes and returns 33 with f = 1.23e-306 = #6ba3b8 5da396e8
g_dfmt(0) gives 9 bytes: "1.23e-306"
strtoId returns 33, consuming 9 bytes.
fI[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306
fI[1] = #6ba3b8 5da396e8 = 1.23e-306
fI[1] == strtod
Input: 1.23e-320
strtod consumes 9 bytes and returns 98 with f = 1.2302234581447039e-320 = #0 9ba
g_dfmt(0) gives 9 bytes: "1.23e-320"
strtoId returns 98, consuming 9 bytes.
fI[0] = #0 9b9 = 1.2297293924988626e-320
fI[1] = #0 9ba = 1.2302234581447039e-320
fI[1] == strtod
Input: 1.23e-20
strtod consumes 8 bytes and returns 33 with f = 1.2300000000000001e-20 = #3bcd0ae4 cf767531
g_dfmt(0) gives 8 bytes: "1.23e-20"
strtoId returns 33, consuming 8 bytes.
fI[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
fI[1] = #3bcd0ae4 cf767531 = 1.2300000000000001e-20
fI[1] == strtod
Input: 1.23456789e307
strtod consumes 14 bytes and returns 33 with f = 1.23456789e+307 = #7fb194b1 4bdaecdc
g_dfmt(0) gives 15 bytes: "1.23456789e+307"
strtoId returns 33, consuming 14 bytes.
fI[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307
fI[1] = #7fb194b1 4bdaecdc = 1.23456789e+307
fI[1] == strtod
Input: 1.23456589e-307
strtod consumes 15 bytes and returns 17 with f = 1.2345658899999999e-307 = #363196 bb9845fa
g_dfmt(0) gives 15 bytes: "1.23456589e-307"
strtoId returns 17, consuming 15 bytes.
fI[0] = #363196 bb9845fa = 1.2345658899999999e-307
fI[1] = #363196 bb9845fb = 1.2345658900000001e-307
fI[0] == strtod
Input: 1.234567890123456789
strtod consumes 20 bytes and returns 17 with f = 1.2345678901234567 = #3ff3c0ca 428c59fb
g_dfmt(0) gives 18 bytes: "1.2345678901234567"
strtoId returns 17, consuming 20 bytes.
fI[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
fI[1] = #3ff3c0ca 428c59fc = 1.2345678901234569
fI[0] == strtod
Input: 1.234567890123456789e301
strtod consumes 24 bytes and returns 17 with f = 1.2345678901234568e+301 = #7e726f51 75f56413
g_dfmt(0) gives 23 bytes: "1.2345678901234568e+301"
strtoId returns 17, consuming 24 bytes.
fI[0] = #7e726f51 75f56413 = 1.2345678901234568e+301
fI[1] = #7e726f51 75f56414 = 1.234567890123457e+301
fI[0] == strtod
Input: 1.234567890123456789e-301
strtod consumes 25 bytes and returns 17 with f = 1.2345678901234567e-301 = #1752a64 e34ba0d3
g_dfmt(0) gives 23 bytes: "1.2345678901234567e-301"
strtoId returns 17, consuming 25 bytes.
fI[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301
fI[1] = #1752a64 e34ba0d4 = 1.2345678901234569e-301
fI[0] == strtod
Input: 1.234567890123456789e-321
strtod consumes 25 bytes and returns 98 with f = 1.2351641146031164e-321 = #0 fa
g_dfmt(0) gives 10 bytes: "1.235e-321"
strtoId returns 98, consuming 25 bytes.
fI[0] = #0 f9 = 1.2302234581447039e-321
fI[1] = #0 fa = 1.2351641146031164e-321
fI[1] == strtod
Input: 1e23
strtod consumes 4 bytes and returns 17 with f = 9.9999999999999992e+22 = #44b52d02 c7e14af6
g_dfmt(0) gives 5 bytes: "1e+23"
strtoId returns 17, consuming 4 bytes.
fI[0] = #44b52d02 c7e14af6 = 9.9999999999999992e+22
fI[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23
fI[0] == strtod
Input: 1e310
strtod consumes 5 bytes and returns 163 with f = Infinity = #7ff00000 0
g_dfmt(0) gives 8 bytes: "Infinity"
strtoId returns 163, consuming 5 bytes.
fI[0] = #7fefffff ffffffff = 1.7976931348623157e+308
fI[1] = #7ff00000 0 = Infinity
fI[1] == strtod
Input: 9.0259718793241475e-277
strtod consumes 23 bytes and returns 33 with f = 9.0259718793241479e-277 = #6a00000 0
g_dfmt(0) gives 22 bytes: "9.025971879324148e-277"
strtoId returns 33, consuming 23 bytes.
fI[0] = #69fffff ffffffff = 9.0259718793241469e-277
fI[1] = #6a00000 0 = 9.0259718793241479e-277
fI[1] == strtod
Input: 9.025971879324147880346310405869e-277
strtod consumes 37 bytes and returns 17 with f = 9.0259718793241479e-277 = #6a00000 0
g_dfmt(0) gives 22 bytes: "9.025971879324148e-277"
strtoId returns 17, consuming 37 bytes.
fI[0] = #6a00000 0 = 9.0259718793241479e-277
fI[1] = #6a00000 1 = 9.0259718793241499e-277
fI[0] == strtod
Input: 9.025971879324147880346310405868e-277
strtod consumes 37 bytes and returns 33 with f = 9.0259718793241479e-277 = #6a00000 0
g_dfmt(0) gives 22 bytes: "9.025971879324148e-277"
strtoId returns 33, consuming 37 bytes.
fI[0] = #69fffff ffffffff = 9.0259718793241469e-277
fI[1] = #6a00000 0 = 9.0259718793241479e-277
fI[1] == strtod
Input: 2.2250738585072014e-308
strtod consumes 23 bytes and returns 17 with f = 2.2250738585072014e-308 = #100000 0
g_dfmt(0) gives 23 bytes: "2.2250738585072014e-308"
strtoId returns 17, consuming 23 bytes.
fI[0] = #100000 0 = 2.2250738585072014e-308
fI[1] = #100000 1 = 2.2250738585072019e-308
fI[0] == strtod
Input: 2.2250738585072013e-308
strtod consumes 23 bytes and returns 33 with f = 2.2250738585072014e-308 = #100000 0
g_dfmt(0) gives 23 bytes: "2.2250738585072014e-308"
strtoId returns 33, consuming 23 bytes.
fI[0] = #fffff ffffffff = 2.2250738585072009e-308
fI[1] = #100000 0 = 2.2250738585072014e-308
fI[1] == strtod
Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero)
Input: 1.1
strtod consumes 3 bytes and returns 17 with f = 1.0999999999999999 = #3ff19999 99999999
g_dfmt(0) gives 18 bytes: "1.0999999999999999"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff19999 99999999 = 1.0999999999999999
fI[1] = #3ff19999 9999999a = 1.1000000000000001
fI[0] == strtod
Input: -1.1
strtod consumes 4 bytes and returns 25 with f = -1.0999999999999999 = #bff19999 99999999
g_dfmt(0) gives 19 bytes: "-1.0999999999999999"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff19999 9999999a = -1.1000000000000001
fI[1] = #bff19999 99999999 = -1.0999999999999999
fI[1] == strtod
Input: 1.2
strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333
g_dfmt(0) gives 3 bytes: "1.2"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff33333 33333333 = 1.2
fI[1] = #3ff33333 33333334 = 1.2000000000000002
fI[0] == strtod
Input: -1.2
strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333
g_dfmt(0) gives 4 bytes: "-1.2"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff33333 33333334 = -1.2000000000000002
fI[1] = #bff33333 33333333 = -1.2
fI[1] == strtod
Input: 1.3
strtod consumes 3 bytes and returns 17 with f = 1.2999999999999998 = #3ff4cccc cccccccc
g_dfmt(0) gives 18 bytes: "1.2999999999999998"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff4cccc cccccccc = 1.2999999999999998
fI[1] = #3ff4cccc cccccccd = 1.3
fI[0] == strtod
Input: -1.3
strtod consumes 4 bytes and returns 25 with f = -1.2999999999999998 = #bff4cccc cccccccc
g_dfmt(0) gives 19 bytes: "-1.2999999999999998"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff4cccc cccccccd = -1.3
fI[1] = #bff4cccc cccccccc = -1.2999999999999998
fI[1] == strtod
Input: 1.4
strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666
g_dfmt(0) gives 3 bytes: "1.4"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff66666 66666666 = 1.3999999999999999
fI[1] = #3ff66666 66666667 = 1.4000000000000001
fI[0] == strtod
Input: -1.4
strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666
g_dfmt(0) gives 4 bytes: "-1.4"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff66666 66666667 = -1.4000000000000001
fI[1] = #bff66666 66666666 = -1.3999999999999999
fI[1] == strtod
Input: 1.5
strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0
g_dfmt(0) gives 3 bytes: "1.5"
strtoId returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtod
Input: -1.5
strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0
g_dfmt(0) gives 4 bytes: "-1.5"
strtoId returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtod
Input: 1.6
strtod consumes 3 bytes and returns 17 with f = 1.5999999999999999 = #3ff99999 99999999
g_dfmt(0) gives 18 bytes: "1.5999999999999999"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff99999 99999999 = 1.5999999999999999
fI[1] = #3ff99999 9999999a = 1.6000000000000001
fI[0] == strtod
Input: -1.6
strtod consumes 4 bytes and returns 25 with f = -1.5999999999999999 = #bff99999 99999999
g_dfmt(0) gives 19 bytes: "-1.5999999999999999"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff99999 9999999a = -1.6000000000000001
fI[1] = #bff99999 99999999 = -1.5999999999999999
fI[1] == strtod
Input: 1.7
strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333
g_dfmt(0) gives 3 bytes: "1.7"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffb3333 33333333 = 1.7
fI[1] = #3ffb3333 33333334 = 1.7000000000000002
fI[0] == strtod
Input: -1.7
strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333
g_dfmt(0) gives 4 bytes: "-1.7"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffb3333 33333334 = -1.7000000000000002
fI[1] = #bffb3333 33333333 = -1.7
fI[1] == strtod
Input: 1.8
strtod consumes 3 bytes and returns 17 with f = 1.7999999999999998 = #3ffccccc cccccccc
g_dfmt(0) gives 18 bytes: "1.7999999999999998"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ffccccc cccccccc = 1.7999999999999998
fI[1] = #3ffccccc cccccccd = 1.8
fI[0] == strtod
Input: -1.8
strtod consumes 4 bytes and returns 25 with f = -1.7999999999999998 = #bffccccc cccccccc
g_dfmt(0) gives 19 bytes: "-1.7999999999999998"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bffccccc cccccccd = -1.8
fI[1] = #bffccccc cccccccc = -1.7999999999999998
fI[1] == strtod
Input: 1.9
strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666
g_dfmt(0) gives 3 bytes: "1.9"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffe6666 66666666 = 1.8999999999999999
fI[1] = #3ffe6666 66666667 = 1.9000000000000001
fI[0] == strtod
Input: -1.9
strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666
g_dfmt(0) gives 4 bytes: "-1.9"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffe6666 66666667 = -1.9000000000000001
fI[1] = #bffe6666 66666666 = -1.8999999999999999
fI[1] == strtod
Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest)
Input: 1.1
strtod consumes 3 bytes and returns 33 with f = 1.1000000000000001 = #3ff19999 9999999a
g_dfmt(0) gives 3 bytes: "1.1"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff19999 99999999 = 1.0999999999999999
fI[1] = #3ff19999 9999999a = 1.1000000000000001
fI[1] == strtod
Input: -1.1
strtod consumes 4 bytes and returns 41 with f = -1.1000000000000001 = #bff19999 9999999a
g_dfmt(0) gives 4 bytes: "-1.1"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff19999 9999999a = -1.1000000000000001
fI[1] = #bff19999 99999999 = -1.0999999999999999
fI[0] == strtod
Input: 1.2
strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333
g_dfmt(0) gives 3 bytes: "1.2"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff33333 33333333 = 1.2
fI[1] = #3ff33333 33333334 = 1.2000000000000002
fI[0] == strtod
Input: -1.2
strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333
g_dfmt(0) gives 4 bytes: "-1.2"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff33333 33333334 = -1.2000000000000002
fI[1] = #bff33333 33333333 = -1.2
fI[1] == strtod
Input: 1.3
strtod consumes 3 bytes and returns 33 with f = 1.3 = #3ff4cccc cccccccd
g_dfmt(0) gives 3 bytes: "1.3"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff4cccc cccccccc = 1.2999999999999998
fI[1] = #3ff4cccc cccccccd = 1.3
fI[1] == strtod
Input: -1.3
strtod consumes 4 bytes and returns 41 with f = -1.3 = #bff4cccc cccccccd
g_dfmt(0) gives 4 bytes: "-1.3"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff4cccc cccccccd = -1.3
fI[1] = #bff4cccc cccccccc = -1.2999999999999998
fI[0] == strtod
Input: 1.4
strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666
g_dfmt(0) gives 3 bytes: "1.4"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff66666 66666666 = 1.3999999999999999
fI[1] = #3ff66666 66666667 = 1.4000000000000001
fI[0] == strtod
Input: -1.4
strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666
g_dfmt(0) gives 4 bytes: "-1.4"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff66666 66666667 = -1.4000000000000001
fI[1] = #bff66666 66666666 = -1.3999999999999999
fI[1] == strtod
Input: 1.5
strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0
g_dfmt(0) gives 3 bytes: "1.5"
strtoId returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtod
Input: -1.5
strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0
g_dfmt(0) gives 4 bytes: "-1.5"
strtoId returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtod
Input: 1.6
strtod consumes 3 bytes and returns 33 with f = 1.6000000000000001 = #3ff99999 9999999a
g_dfmt(0) gives 3 bytes: "1.6"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff99999 99999999 = 1.5999999999999999
fI[1] = #3ff99999 9999999a = 1.6000000000000001
fI[1] == strtod
Input: -1.6
strtod consumes 4 bytes and returns 41 with f = -1.6000000000000001 = #bff99999 9999999a
g_dfmt(0) gives 4 bytes: "-1.6"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff99999 9999999a = -1.6000000000000001
fI[1] = #bff99999 99999999 = -1.5999999999999999
fI[0] == strtod
Input: 1.7
strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333
g_dfmt(0) gives 3 bytes: "1.7"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffb3333 33333333 = 1.7
fI[1] = #3ffb3333 33333334 = 1.7000000000000002
fI[0] == strtod
Input: -1.7
strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333
g_dfmt(0) gives 4 bytes: "-1.7"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffb3333 33333334 = -1.7000000000000002
fI[1] = #bffb3333 33333333 = -1.7
fI[1] == strtod
Input: 1.8
strtod consumes 3 bytes and returns 33 with f = 1.8 = #3ffccccc cccccccd
g_dfmt(0) gives 3 bytes: "1.8"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ffccccc cccccccc = 1.7999999999999998
fI[1] = #3ffccccc cccccccd = 1.8
fI[1] == strtod
Input: -1.8
strtod consumes 4 bytes and returns 41 with f = -1.8 = #bffccccc cccccccd
g_dfmt(0) gives 4 bytes: "-1.8"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bffccccc cccccccd = -1.8
fI[1] = #bffccccc cccccccc = -1.7999999999999998
fI[0] == strtod
Input: 1.9
strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666
g_dfmt(0) gives 3 bytes: "1.9"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffe6666 66666666 = 1.8999999999999999
fI[1] = #3ffe6666 66666667 = 1.9000000000000001
fI[0] == strtod
Input: -1.9
strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666
g_dfmt(0) gives 4 bytes: "-1.9"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffe6666 66666667 = -1.9000000000000001
fI[1] = #bffe6666 66666666 = -1.8999999999999999
fI[1] == strtod
Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity)
Input: 1.1
strtod consumes 3 bytes and returns 33 with f = 1.1000000000000001 = #3ff19999 9999999a
g_dfmt(0) gives 3 bytes: "1.1"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff19999 99999999 = 1.0999999999999999
fI[1] = #3ff19999 9999999a = 1.1000000000000001
fI[1] == strtod
Input: -1.1
strtod consumes 4 bytes and returns 25 with f = -1.0999999999999999 = #bff19999 99999999
g_dfmt(0) gives 19 bytes: "-1.0999999999999999"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff19999 9999999a = -1.1000000000000001
fI[1] = #bff19999 99999999 = -1.0999999999999999
fI[1] == strtod
Input: 1.2
strtod consumes 3 bytes and returns 33 with f = 1.2000000000000002 = #3ff33333 33333334
g_dfmt(0) gives 18 bytes: "1.2000000000000002"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff33333 33333333 = 1.2
fI[1] = #3ff33333 33333334 = 1.2000000000000002
fI[1] == strtod
Input: -1.2
strtod consumes 4 bytes and returns 25 with f = -1.2 = #bff33333 33333333
g_dfmt(0) gives 4 bytes: "-1.2"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff33333 33333334 = -1.2000000000000002
fI[1] = #bff33333 33333333 = -1.2
fI[1] == strtod
Input: 1.3
strtod consumes 3 bytes and returns 33 with f = 1.3 = #3ff4cccc cccccccd
g_dfmt(0) gives 3 bytes: "1.3"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff4cccc cccccccc = 1.2999999999999998
fI[1] = #3ff4cccc cccccccd = 1.3
fI[1] == strtod
Input: -1.3
strtod consumes 4 bytes and returns 25 with f = -1.2999999999999998 = #bff4cccc cccccccc
g_dfmt(0) gives 19 bytes: "-1.2999999999999998"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff4cccc cccccccd = -1.3
fI[1] = #bff4cccc cccccccc = -1.2999999999999998
fI[1] == strtod
Input: 1.4
strtod consumes 3 bytes and returns 33 with f = 1.4000000000000001 = #3ff66666 66666667
g_dfmt(0) gives 18 bytes: "1.4000000000000001"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff66666 66666666 = 1.3999999999999999
fI[1] = #3ff66666 66666667 = 1.4000000000000001
fI[1] == strtod
Input: -1.4
strtod consumes 4 bytes and returns 25 with f = -1.3999999999999999 = #bff66666 66666666
g_dfmt(0) gives 4 bytes: "-1.4"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff66666 66666667 = -1.4000000000000001
fI[1] = #bff66666 66666666 = -1.3999999999999999
fI[1] == strtod
Input: 1.5
strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0
g_dfmt(0) gives 3 bytes: "1.5"
strtoId returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtod
Input: -1.5
strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0
g_dfmt(0) gives 4 bytes: "-1.5"
strtoId returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtod
Input: 1.6
strtod consumes 3 bytes and returns 33 with f = 1.6000000000000001 = #3ff99999 9999999a
g_dfmt(0) gives 3 bytes: "1.6"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff99999 99999999 = 1.5999999999999999
fI[1] = #3ff99999 9999999a = 1.6000000000000001
fI[1] == strtod
Input: -1.6
strtod consumes 4 bytes and returns 25 with f = -1.5999999999999999 = #bff99999 99999999
g_dfmt(0) gives 19 bytes: "-1.5999999999999999"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff99999 9999999a = -1.6000000000000001
fI[1] = #bff99999 99999999 = -1.5999999999999999
fI[1] == strtod
Input: 1.7
strtod consumes 3 bytes and returns 33 with f = 1.7000000000000002 = #3ffb3333 33333334
g_dfmt(0) gives 18 bytes: "1.7000000000000002"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffb3333 33333333 = 1.7
fI[1] = #3ffb3333 33333334 = 1.7000000000000002
fI[1] == strtod
Input: -1.7
strtod consumes 4 bytes and returns 25 with f = -1.7 = #bffb3333 33333333
g_dfmt(0) gives 4 bytes: "-1.7"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffb3333 33333334 = -1.7000000000000002
fI[1] = #bffb3333 33333333 = -1.7
fI[1] == strtod
Input: 1.8
strtod consumes 3 bytes and returns 33 with f = 1.8 = #3ffccccc cccccccd
g_dfmt(0) gives 3 bytes: "1.8"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ffccccc cccccccc = 1.7999999999999998
fI[1] = #3ffccccc cccccccd = 1.8
fI[1] == strtod
Input: -1.8
strtod consumes 4 bytes and returns 25 with f = -1.7999999999999998 = #bffccccc cccccccc
g_dfmt(0) gives 19 bytes: "-1.7999999999999998"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bffccccc cccccccd = -1.8
fI[1] = #bffccccc cccccccc = -1.7999999999999998
fI[1] == strtod
Input: 1.9
strtod consumes 3 bytes and returns 33 with f = 1.9000000000000001 = #3ffe6666 66666667
g_dfmt(0) gives 18 bytes: "1.9000000000000001"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffe6666 66666666 = 1.8999999999999999
fI[1] = #3ffe6666 66666667 = 1.9000000000000001
fI[1] == strtod
Input: -1.9
strtod consumes 4 bytes and returns 25 with f = -1.8999999999999999 = #bffe6666 66666666
g_dfmt(0) gives 4 bytes: "-1.9"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffe6666 66666667 = -1.9000000000000001
fI[1] = #bffe6666 66666666 = -1.8999999999999999
fI[1] == strtod
Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity)
Input: 1.1
strtod consumes 3 bytes and returns 17 with f = 1.0999999999999999 = #3ff19999 99999999
g_dfmt(0) gives 18 bytes: "1.0999999999999999"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff19999 99999999 = 1.0999999999999999
fI[1] = #3ff19999 9999999a = 1.1000000000000001
fI[0] == strtod
Input: -1.1
strtod consumes 4 bytes and returns 41 with f = -1.1000000000000001 = #bff19999 9999999a
g_dfmt(0) gives 4 bytes: "-1.1"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff19999 9999999a = -1.1000000000000001
fI[1] = #bff19999 99999999 = -1.0999999999999999
fI[0] == strtod
Input: 1.2
strtod consumes 3 bytes and returns 17 with f = 1.2 = #3ff33333 33333333
g_dfmt(0) gives 3 bytes: "1.2"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff33333 33333333 = 1.2
fI[1] = #3ff33333 33333334 = 1.2000000000000002
fI[0] == strtod
Input: -1.2
strtod consumes 4 bytes and returns 41 with f = -1.2000000000000002 = #bff33333 33333334
g_dfmt(0) gives 19 bytes: "-1.2000000000000002"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff33333 33333334 = -1.2000000000000002
fI[1] = #bff33333 33333333 = -1.2
fI[0] == strtod
Input: 1.3
strtod consumes 3 bytes and returns 17 with f = 1.2999999999999998 = #3ff4cccc cccccccc
g_dfmt(0) gives 18 bytes: "1.2999999999999998"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff4cccc cccccccc = 1.2999999999999998
fI[1] = #3ff4cccc cccccccd = 1.3
fI[0] == strtod
Input: -1.3
strtod consumes 4 bytes and returns 41 with f = -1.3 = #bff4cccc cccccccd
g_dfmt(0) gives 4 bytes: "-1.3"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff4cccc cccccccd = -1.3
fI[1] = #bff4cccc cccccccc = -1.2999999999999998
fI[0] == strtod
Input: 1.4
strtod consumes 3 bytes and returns 17 with f = 1.3999999999999999 = #3ff66666 66666666
g_dfmt(0) gives 3 bytes: "1.4"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ff66666 66666666 = 1.3999999999999999
fI[1] = #3ff66666 66666667 = 1.4000000000000001
fI[0] == strtod
Input: -1.4
strtod consumes 4 bytes and returns 41 with f = -1.4000000000000001 = #bff66666 66666667
g_dfmt(0) gives 19 bytes: "-1.4000000000000001"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bff66666 66666667 = -1.4000000000000001
fI[1] = #bff66666 66666666 = -1.3999999999999999
fI[0] == strtod
Input: 1.5
strtod consumes 3 bytes and returns 1 with f = 1.5 = #3ff80000 0
g_dfmt(0) gives 3 bytes: "1.5"
strtoId returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtod
Input: -1.5
strtod consumes 4 bytes and returns 9 with f = -1.5 = #bff80000 0
g_dfmt(0) gives 4 bytes: "-1.5"
strtoId returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtod
Input: 1.6
strtod consumes 3 bytes and returns 17 with f = 1.5999999999999999 = #3ff99999 99999999
g_dfmt(0) gives 18 bytes: "1.5999999999999999"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ff99999 99999999 = 1.5999999999999999
fI[1] = #3ff99999 9999999a = 1.6000000000000001
fI[0] == strtod
Input: -1.6
strtod consumes 4 bytes and returns 41 with f = -1.6000000000000001 = #bff99999 9999999a
g_dfmt(0) gives 4 bytes: "-1.6"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bff99999 9999999a = -1.6000000000000001
fI[1] = #bff99999 99999999 = -1.5999999999999999
fI[0] == strtod
Input: 1.7
strtod consumes 3 bytes and returns 17 with f = 1.7 = #3ffb3333 33333333
g_dfmt(0) gives 3 bytes: "1.7"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffb3333 33333333 = 1.7
fI[1] = #3ffb3333 33333334 = 1.7000000000000002
fI[0] == strtod
Input: -1.7
strtod consumes 4 bytes and returns 41 with f = -1.7000000000000002 = #bffb3333 33333334
g_dfmt(0) gives 19 bytes: "-1.7000000000000002"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffb3333 33333334 = -1.7000000000000002
fI[1] = #bffb3333 33333333 = -1.7
fI[0] == strtod
Input: 1.8
strtod consumes 3 bytes and returns 17 with f = 1.7999999999999998 = #3ffccccc cccccccc
g_dfmt(0) gives 18 bytes: "1.7999999999999998"
strtoId returns 33, consuming 3 bytes.
fI[0] = #3ffccccc cccccccc = 1.7999999999999998
fI[1] = #3ffccccc cccccccd = 1.8
fI[0] == strtod
Input: -1.8
strtod consumes 4 bytes and returns 41 with f = -1.8 = #bffccccc cccccccd
g_dfmt(0) gives 4 bytes: "-1.8"
strtoId returns 41, consuming 4 bytes.
fI[0] = #bffccccc cccccccd = -1.8
fI[1] = #bffccccc cccccccc = -1.7999999999999998
fI[0] == strtod
Input: 1.9
strtod consumes 3 bytes and returns 17 with f = 1.8999999999999999 = #3ffe6666 66666666
g_dfmt(0) gives 3 bytes: "1.9"
strtoId returns 17, consuming 3 bytes.
fI[0] = #3ffe6666 66666666 = 1.8999999999999999
fI[1] = #3ffe6666 66666667 = 1.9000000000000001
fI[0] == strtod
Input: -1.9
strtod consumes 4 bytes and returns 41 with f = -1.9000000000000001 = #bffe6666 66666667
g_dfmt(0) gives 19 bytes: "-1.9000000000000001"
strtoId returns 25, consuming 4 bytes.
fI[0] = #bffe6666 66666667 = -1.9000000000000001
fI[1] = #bffe6666 66666666 = -1.8999999999999999
fI[0] == strtod

168
contrib/gdtoa/test/dI.out Normal file
View File

@ -0,0 +1,168 @@
Input: 1.23
strtodI consumes 4 bytes and returns 17
dd[0] = #3ff3ae14 7ae147ae = 1.23
dd[1] = #3ff3ae14 7ae147af = 1.2300000000000002
Input: 1.23e+20
strtodI consumes 8 bytes and returns 1
dd[0] = #441aabdf 2145b430 = 1.23e+20
dd[1] = #441aabdf 2145b430 = 1.23e+20
Input: 1.23e-20
strtodI consumes 8 bytes and returns 33
dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
dd[1] = #3bcd0ae4 cf767531 = 1.23e-20
Input: 1.23456789
strtodI consumes 10 bytes and returns 17
dd[0] = #3ff3c0ca 4283de1b = 1.23456789
dd[1] = #3ff3c0ca 4283de1c = 1.2345678900000001
Input: 1.23456589e+20
strtodI consumes 14 bytes and returns 17
dd[0] = #441ac537 a660b997 = 1.23456589e+20
dd[1] = #441ac537 a660b998 = 123456589000000010000
Input: 1.23e+30
strtodI consumes 8 bytes and returns 17
dd[0] = #462f0cb0 4e8fb790 = 1.23e+30
dd[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30
Input: 1.23e-30
strtodI consumes 8 bytes and returns 33
dd[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30
dd[1] = #39b8f286 6f5010ab = 1.23e-30
Input: 1.23456789e-20
strtodI consumes 14 bytes and returns 17
dd[0] = #3bcd2681 471e7ada = 1.23456789e-20
dd[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20
Input: 1.23456789e-30
strtodI consumes 14 bytes and returns 17
dd[0] = #39b90a3e 33bbd995 = 1.23456789e-30
dd[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30
Input: 1.234567890123456789
strtodI consumes 20 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.23456789012345678901234567890123456789
strtodI consumes 40 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.23e306
strtodI consumes 8 bytes and returns 33
dd[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306
dd[1] = #7f7c0676 cd1c61f5 = 1.23e+306
Input: 1.23e-306
strtodI consumes 9 bytes and returns 33
dd[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306
dd[1] = #6ba3b8 5da396e8 = 1.23e-306
Input: 1.23e-320
strtodI consumes 9 bytes and returns 98
dd[0] = #0 9b9 = 1.2297e-320
dd[1] = #0 9ba = 1.23e-320
Input: 1.23e-20
strtodI consumes 8 bytes and returns 33
dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
dd[1] = #3bcd0ae4 cf767531 = 1.23e-20
Input: 1.23456789e307
strtodI consumes 14 bytes and returns 33
dd[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307
dd[1] = #7fb194b1 4bdaecdc = 1.23456789e+307
Input: 1.23456589e-307
strtodI consumes 15 bytes and returns 17
dd[0] = #363196 bb9845fa = 1.23456589e-307
dd[1] = #363196 bb9845fb = 1.2345658900000001e-307
Input: 1.234567890123456789
strtodI consumes 20 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.234567890123456789e301
strtodI consumes 24 bytes and returns 17
dd[0] = #7e726f51 75f56413 = 1.2345678901234568e+301
dd[1] = #7e726f51 75f56414 = 1.234567890123457e+301
Input: 1.234567890123456789e-301
strtodI consumes 25 bytes and returns 17
dd[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301
dd[1] = #1752a64 e34ba0d4 = 1.234567890123457e-301
Input: 1.234567890123456789e-321
strtodI consumes 25 bytes and returns 98
dd[0] = #0 f9 = 1.23e-321
dd[1] = #0 fa = 1.235e-321
Input: 1e23
strtodI consumes 4 bytes and returns 17
dd[0] = #44b52d02 c7e14af6 = 1e+23
dd[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23
Input: 1e310
strtodI consumes 5 bytes and returns 163
dd[0] = #7fefffff ffffffff = 1.7976931348623157e+308
dd[1] = #7ff00000 0 = Infinity
Input: 9.0259718793241475e-277
strtodI consumes 23 bytes and returns 33
dd[0] = #69fffff ffffffff = 9.025971879324147e-277
dd[1] = #6a00000 0 = 9.025971879324148e-277
Input: 9.025971879324147880346310405869e-277
strtodI consumes 37 bytes and returns 17
dd[0] = #6a00000 0 = 9.025971879324148e-277
dd[1] = #6a00000 1 = 9.02597187932415e-277
Input: 9.025971879324147880346310405868e-277
strtodI consumes 37 bytes and returns 33
dd[0] = #69fffff ffffffff = 9.025971879324147e-277
dd[1] = #6a00000 0 = 9.025971879324148e-277
Input: 2.2250738585072014e-308
strtodI consumes 23 bytes and returns 17
dd[0] = #100000 0 = 2.2250738585072014e-308
dd[1] = #100000 1 = 2.225073858507202e-308
Input: 2.2250738585072013e-308
strtodI consumes 23 bytes and returns 33
dd[0] = #fffff ffffffff = 2.225073858507201e-308
dd[1] = #100000 0 = 2.2250738585072014e-308

168
contrib/gdtoa/test/dIsi.out Normal file
View File

@ -0,0 +1,168 @@
Input: 1.23
strtodI consumes 4 bytes and returns 17
dd[0] = #3ff3ae14 7ae147ae = 1.23
dd[1] = #3ff3ae14 7ae147af = 1.2300000000000002
Input: 1.23e+20
strtodI consumes 8 bytes and returns 1
dd[0] = #441aabdf 2145b430 = 1.23e+20
dd[1] = #441aabdf 2145b430 = 1.23e+20
Input: 1.23e-20
strtodI consumes 8 bytes and returns 33
dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
dd[1] = #3bcd0ae4 cf767531 = 1.23e-20
Input: 1.23456789
strtodI consumes 10 bytes and returns 17
dd[0] = #3ff3c0ca 4283de1b = 1.23456789
dd[1] = #3ff3c0ca 4283de1c = 1.2345678900000001
Input: 1.23456589e+20
strtodI consumes 14 bytes and returns 17
dd[0] = #441ac537 a660b997 = 1.23456589e+20
dd[1] = #441ac537 a660b998 = 123456589000000010000
Input: 1.23e+30
strtodI consumes 8 bytes and returns 17
dd[0] = #462f0cb0 4e8fb790 = 1.23e+30
dd[1] = #462f0cb0 4e8fb791 = 1.2300000000000001e+30
Input: 1.23e-30
strtodI consumes 8 bytes and returns 33
dd[0] = #39b8f286 6f5010aa = 1.2299999999999999e-30
dd[1] = #39b8f286 6f5010ab = 1.23e-30
Input: 1.23456789e-20
strtodI consumes 14 bytes and returns 17
dd[0] = #3bcd2681 471e7ada = 1.23456789e-20
dd[1] = #3bcd2681 471e7adb = 1.2345678900000001e-20
Input: 1.23456789e-30
strtodI consumes 14 bytes and returns 17
dd[0] = #39b90a3e 33bbd995 = 1.23456789e-30
dd[1] = #39b90a3e 33bbd996 = 1.2345678900000002e-30
Input: 1.234567890123456789
strtodI consumes 20 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.23456789012345678901234567890123456789
strtodI consumes 40 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.23e306
strtodI consumes 8 bytes and returns 33
dd[0] = #7f7c0676 cd1c61f4 = 1.2299999999999999e+306
dd[1] = #7f7c0676 cd1c61f5 = 1.23e+306
Input: 1.23e-306
strtodI consumes 9 bytes and returns 33
dd[0] = #6ba3b8 5da396e7 = 1.2299999999999999e-306
dd[1] = #6ba3b8 5da396e8 = 1.23e-306
Input: 1.23e-320
strtodI consumes 9 bytes and returns 80
dd[0] = #0 0 = 0
dd[1] = #100000 0 = 2.2250738585072014e-308
Input: 1.23e-20
strtodI consumes 8 bytes and returns 33
dd[0] = #3bcd0ae4 cf767530 = 1.2299999999999999e-20
dd[1] = #3bcd0ae4 cf767531 = 1.23e-20
Input: 1.23456789e307
strtodI consumes 14 bytes and returns 33
dd[0] = #7fb194b1 4bdaecdb = 1.2345678899999998e+307
dd[1] = #7fb194b1 4bdaecdc = 1.23456789e+307
Input: 1.23456589e-307
strtodI consumes 15 bytes and returns 17
dd[0] = #363196 bb9845fa = 1.23456589e-307
dd[1] = #363196 bb9845fb = 1.2345658900000001e-307
Input: 1.234567890123456789
strtodI consumes 20 bytes and returns 17
dd[0] = #3ff3c0ca 428c59fb = 1.2345678901234567
dd[1] = #3ff3c0ca 428c59fc = 1.234567890123457
Input: 1.234567890123456789e301
strtodI consumes 24 bytes and returns 17
dd[0] = #7e726f51 75f56413 = 1.2345678901234568e+301
dd[1] = #7e726f51 75f56414 = 1.234567890123457e+301
Input: 1.234567890123456789e-301
strtodI consumes 25 bytes and returns 17
dd[0] = #1752a64 e34ba0d3 = 1.2345678901234567e-301
dd[1] = #1752a64 e34ba0d4 = 1.234567890123457e-301
Input: 1.234567890123456789e-321
strtodI consumes 25 bytes and returns 80
dd[0] = #0 0 = 0
dd[1] = #100000 0 = 2.2250738585072014e-308
Input: 1e23
strtodI consumes 4 bytes and returns 17
dd[0] = #44b52d02 c7e14af6 = 1e+23
dd[1] = #44b52d02 c7e14af7 = 1.0000000000000001e+23
Input: 1e310
strtodI consumes 5 bytes and returns 163
dd[0] = #7fefffff ffffffff = 1.7976931348623157e+308
dd[1] = #7ff00000 0 = Infinity
Input: 9.0259718793241475e-277
strtodI consumes 23 bytes and returns 33
dd[0] = #69fffff ffffffff = 9.025971879324147e-277
dd[1] = #6a00000 0 = 9.025971879324148e-277
Input: 9.025971879324147880346310405869e-277
strtodI consumes 37 bytes and returns 17
dd[0] = #6a00000 0 = 9.025971879324148e-277
dd[1] = #6a00000 1 = 9.02597187932415e-277
Input: 9.025971879324147880346310405868e-277
strtodI consumes 37 bytes and returns 33
dd[0] = #69fffff ffffffff = 9.025971879324147e-277
dd[1] = #6a00000 0 = 9.025971879324148e-277
Input: 2.2250738585072014e-308
strtodI consumes 23 bytes and returns 17
dd[0] = #100000 0 = 2.2250738585072014e-308
dd[1] = #100000 1 = 2.225073858507202e-308
Input: 2.2250738585072013e-308
strtodI consumes 23 bytes and returns 33
dd[0] = #0 0 = 0
dd[1] = #100000 0 = 2.2250738585072014e-308

View File

@ -0,0 +1,88 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
#include <stdio.h>
#include <stdlib.h>
static char ibuf[2048];
#define U (unsigned long)
static void
#ifdef KR_headers
dshow(what, d) char *what; double d;
#else
dshow(char *what, double d)
#endif
{
char buf[32];
g_dfmt(buf, &d, 0, sizeof(buf));
printf("%s = #%lx %lx = %s\n", what,
U ((ULong*)&d)[_0], U ((ULong*)&d)[_1], buf);
}
int
main(Void)
{
/* Input: one number per line */
char *s, *se, *se1;
int i, j;
double dd[2], dd1, dd2;
static char cfmt[] = "%s consumes %d bytes and returns %d\n";
while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
while(*s <= ' ')
if (!*s++)
continue;
printf("\nInput: %s", ibuf);
i = strtodI(ibuf, &se, dd);
printf(cfmt, "strtodI", (int)(se-ibuf), i);
dshow("dd[0]", dd[0]);
dshow("dd[1]", dd[1]);
printf("\n");
j = strtoId(ibuf, &se1, &dd1, &dd2);
if (j != i || se != se1
|| dd[0] != dd1 || dd[1] != dd2) {
printf(cfmt, "**** strtoId", (int)(se-ibuf), j);
dshow("dd1", dd1);
dshow("dd2", dd2);
}
}
return 0;
}

1356
contrib/gdtoa/test/dd.out Normal file

File diff suppressed because it is too large Load Diff

376
contrib/gdtoa/test/ddsi.out Normal file
View File

@ -0,0 +1,376 @@
Input: 1.23
strtopdd consumes 4 bytes and returns 17
dd[0] = 1.23 = #3ff3ae14 7ae147ae
dd[1] = 1.7763568394002496e-17 = #3c747ae1 47ae1478
g_ddfmt(0) gives 4 bytes: "1.23"
strtoIdd returns 17, consuming 4 bytes.
ddI[0] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1478
= 1.23 + 1.7763568394002496e-17
ddI[1] = #3ff3ae14 7ae147ae + 3c747ae1 47ae1480
= 1.23 + 1.776356839400252e-17
ddI[0] == strtod
Input: 1.23e+20
strtopdd consumes 8 bytes and returns 1
dd[0] = 1.23e+20 = #441aabdf 2145b430
dd[1] = 0 = #0 0
g_ddfmt(0) gives 8 bytes: "1.23e+20"
strtoIdd returns 1, consuming 8 bytes.
ddI[0] == ddI[1] == strtopdd
Input: 1.23e-20
strtopdd consumes 8 bytes and returns 33
dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530
dd[1] = 9.304023318521521e-37 = #3873c997 955b2691
g_ddfmt(0) gives 8 bytes: "1.23e-20"
strtoIdd returns 33, consuming 8 bytes.
ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690
= 1.2299999999999999e-20 + 9.3040233185215194e-37
ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691
= 1.2299999999999999e-20 + 9.3040233185215211e-37
ddI[1] == strtod
Input: 1.23456789
strtopdd consumes 10 bytes and returns 17
dd[0] = 1.23456789 = #3ff3c0ca 4283de1b
dd[1] = 1.0990618193318369e-16 = #3c9fada5 144c1252
g_ddfmt(0) gives 10 bytes: "1.23456789"
strtoIdd returns 17, consuming 10 bytes.
ddI[0] = #3ff3c0ca 4283de1b + 3c9fada5 144c1252
= 1.2345678899999999 + 1.0990618193318369e-16
ddI[1] = #3ff3c0ca 4283de1b + 3c9fada5 144c1254
= 1.2345678899999999 + 1.0990618193318371e-16
ddI[0] == strtod
Input: 1.23456589e+20
strtopdd consumes 14 bytes and returns 1
dd[0] = 1.23456589e+20 = #441ac537 a660b997
dd[1] = 4096 = #40b00000 0
g_ddfmt(0) gives 14 bytes: "1.23456589e+20"
strtoIdd returns 1, consuming 14 bytes.
ddI[0] == ddI[1] == strtopdd
Input: 1.23e+30
strtopdd consumes 8 bytes and returns 1
dd[0] = 1.23e+30 = #462f0cb0 4e8fb790
dd[1] = 40281156091904 = #42c25158 0
g_ddfmt(0) gives 8 bytes: "1.23e+30"
strtoIdd returns 1, consuming 8 bytes.
ddI[0] == ddI[1] == strtopdd
Input: 1.23e-30
strtopdd consumes 8 bytes and returns 17
dd[0] = 1.2299999999999999e-30 = #39b8f286 6f5010aa
dd[1] = 1.076909723013918e-46 = #3663ac7f 3dafd174
g_ddfmt(0) gives 8 bytes: "1.23e-30"
strtoIdd returns 17, consuming 8 bytes.
ddI[0] = #39b8f286 6f5010aa + 3663ac7f 3dafd174
= 1.2299999999999999e-30 + 1.076909723013918e-46
ddI[1] = #39b8f286 6f5010aa + 3663ac7f 3dafd175
= 1.2299999999999999e-30 + 1.0769097230139181e-46
ddI[0] == strtod
Input: 1.23456789e-20
strtopdd consumes 14 bytes and returns 17
dd[0] = 1.23456789e-20 = #3bcd2681 471e7ada
dd[1] = 6.247111971663133e-37 = #386a9280 a761b07e
g_ddfmt(0) gives 14 bytes: "1.23456789e-20"
strtoIdd returns 17, consuming 14 bytes.
ddI[0] = #3bcd2681 471e7ada + 386a9280 a761b07e
= 1.2345678899999999e-20 + 6.2471119716631328e-37
ddI[1] = #3bcd2681 471e7ada + 386a9280 a761b080
= 1.2345678899999999e-20 + 6.2471119716631345e-37
ddI[0] == strtod
Input: 1.23456789e-30
strtopdd consumes 14 bytes and returns 33
dd[0] = 1.23456789e-30 = #39b90a3e 33bbd995
dd[1] = 2.1567930523648577e-47 = #363f8585 55a6b1a0
g_ddfmt(0) gives 14 bytes: "1.23456789e-30"
strtoIdd returns 33, consuming 14 bytes.
ddI[0] = #39b90a3e 33bbd995 + 363f8585 55a6b198
= 1.23456789e-30 + 2.1567930523648558e-47
ddI[1] = #39b90a3e 33bbd995 + 363f8585 55a6b1a0
= 1.23456789e-30 + 2.1567930523648577e-47
ddI[1] == strtod
Input: 1.234567890123456789
strtopdd consumes 20 bytes and returns 33
dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb
dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e
g_ddfmt(0) gives 20 bytes: "1.234567890123456789"
strtoIdd returns 33, consuming 20 bytes.
ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c
= 1.2345678901234567 + 9.8567864525888563e-17
ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e
= 1.2345678901234567 + 9.8567864525888588e-17
ddI[1] == strtod
Input: 1.23456789012345678901234567890123456789
strtopdd consumes 40 bytes and returns 33
dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb
dd[1] = 9.858021020478982e-17 = #3c9c69ef 85adadb6
g_ddfmt(0) gives 34 bytes: "1.23456789012345678901234567890124"
strtoIdd returns 33, consuming 40 bytes.
ddI[0] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb4
= 1.2345678901234567 + 9.8580210204789798e-17
ddI[1] = #3ff3c0ca 428c59fb + 3c9c69ef 85adadb6
= 1.2345678901234567 + 9.8580210204789823e-17
ddI[1] == strtod
Input: 1.23e306
strtopdd consumes 8 bytes and returns 33
dd[0] = 1.2299999999999999e+306 = #7f7c0676 cd1c61f4
dd[1] = 1.3319001448659015e+290 = #7c2b558b e3d3f477
g_ddfmt(0) gives 9 bytes: "1.23e+306"
strtoIdd returns 33, consuming 8 bytes.
ddI[0] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f476
= 1.2299999999999999e+306 + 1.3319001448659013e+290
ddI[1] = #7f7c0676 cd1c61f4 + 7c2b558b e3d3f477
= 1.2299999999999999e+306 + 1.3319001448659015e+290
ddI[1] == strtod
Input: 1.23e-306
strtopdd consumes 9 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 9 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 1.23e-320
strtopdd consumes 9 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 9 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 1.23e-20
strtopdd consumes 8 bytes and returns 33
dd[0] = 1.2299999999999999e-20 = #3bcd0ae4 cf767530
dd[1] = 9.304023318521521e-37 = #3873c997 955b2691
g_ddfmt(0) gives 8 bytes: "1.23e-20"
strtoIdd returns 33, consuming 8 bytes.
ddI[0] = #3bcd0ae4 cf767530 + 3873c997 955b2690
= 1.2299999999999999e-20 + 9.3040233185215194e-37
ddI[1] = #3bcd0ae4 cf767530 + 3873c997 955b2691
= 1.2299999999999999e-20 + 9.3040233185215211e-37
ddI[1] == strtod
Input: 1.23456789e307
strtopdd consumes 14 bytes and returns 33
dd[0] = 1.2345678899999998e+307 = #7fb194b1 4bdaecdb
dd[1] = 2.0137933598720243e+291 = #7c69d48d 192048ca
g_ddfmt(0) gives 15 bytes: "1.23456789e+307"
strtoIdd returns 33, consuming 14 bytes.
ddI[0] = #7fb194b1 4bdaecdb + 7c69d48d 192048c9
= 1.2345678899999998e+307 + 2.013793359872024e+291
ddI[1] = #7fb194b1 4bdaecdb + 7c69d48d 192048ca
= 1.2345678899999998e+307 + 2.0137933598720243e+291
ddI[1] == strtod
Input: 1.23456589e-307
strtopdd consumes 15 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 15 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 1.234567890123456789
strtopdd consumes 20 bytes and returns 33
dd[0] = 1.2345678901234567 = #3ff3c0ca 428c59fb
dd[1] = 9.856786452588859e-17 = #3c9c6906 51a3745e
g_ddfmt(0) gives 20 bytes: "1.234567890123456789"
strtoIdd returns 33, consuming 20 bytes.
ddI[0] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745c
= 1.2345678901234567 + 9.8567864525888563e-17
ddI[1] = #3ff3c0ca 428c59fb + 3c9c6906 51a3745e
= 1.2345678901234567 + 9.8567864525888588e-17
ddI[1] == strtod
Input: 1.234567890123456789e301
strtopdd consumes 24 bytes and returns 33
dd[0] = 1.2345678901234568e+301 = #7e726f51 75f56413
dd[1] = 1.3892003943918827e+283 = #7ab7ea80 76399100
g_ddfmt(0) gives 25 bytes: "1.234567890123456789e+301"
strtoIdd returns 33, consuming 24 bytes.
ddI[0] = #7e726f51 75f56413 + 7ab7ea80 76399080
= 1.2345678901234568e+301 + 1.3892003943918563e+283
ddI[1] = #7e726f51 75f56413 + 7ab7ea80 76399100
= 1.2345678901234568e+301 + 1.3892003943918827e+283
ddI[1] == strtod
Input: 1.234567890123456789e-301
strtopdd consumes 25 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 25 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 1.234567890123456789e-321
strtopdd consumes 25 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 25 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 1e23
strtopdd consumes 4 bytes and returns 1
dd[0] = 1e+23 = #44b52d02 c7e14af6
dd[1] = 8388608 = #41600000 0
g_ddfmt(0) gives 5 bytes: "1e+23"
strtoIdd returns 1, consuming 4 bytes.
ddI[0] == ddI[1] == strtopdd
Input: 1e310
strtopdd consumes 5 bytes and returns 163
dd[0] = Infinity = #7ff00000 0
dd[1] = Infinity = #7ff00000 0
g_ddfmt(0) gives 8 bytes: "Infinity"
strtoIdd returns 163, consuming 5 bytes.
ddI[0] = #7fefffff ffffffff + 7c9fffff ffffffff
= 1.7976931348623157e+308 + 1.9958403095347196e+292
ddI[1] = #7ff00000 0 + 7ff00000 0
= Infinity + Infinity
ddI[1] == strtod
Input: 9.0259718793241475e-277
strtopdd consumes 23 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 23 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 9.025971879324147880346310405869e-277
strtopdd consumes 37 bytes and returns 17
dd[0] = 9.025971879324148e-277 = #6a00000 0
dd[1] = 2.2250738585072014e-308 = #100000 0
g_ddfmt(0) gives 37 bytes: "9.025971879324147880346310405869e-277"
strtoIdd returns 17, consuming 37 bytes.
ddI[0] = #6a00000 0 + 100000 0
= 9.0259718793241479e-277 + 2.2250738585072014e-308
ddI[1] = #6a00000 0 + 200000 0
= 9.0259718793241479e-277 + 4.4501477170144028e-308
ddI[0] == strtod
Input: 9.025971879324147880346310405868e-277
strtopdd consumes 37 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 37 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 2.2250738585072014e-308
strtopdd consumes 23 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 23 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod
Input: 2.2250738585072013e-308
strtopdd consumes 23 bytes and returns 80
dd[0] = 0 = #0 0
dd[1] = 0 = #0 0
g_ddfmt(0) gives 1 bytes: "0"
strtoIdd returns 80, consuming 23 bytes.
ddI[0] = #0 0 + 0 0
= 0 + 0
ddI[1] = #6a00000 0 + 0 0
= 9.0259718793241479e-277 + 0
ddI[0] == strtod

183
contrib/gdtoa/test/ddtest.c Normal file
View File

@ -0,0 +1,183 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_ddfmt, strtoIdd, strtopdd, and strtordd.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex0 hex1 hex2 hex3
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex0 is a string of <= 8 Hex digits for the most significant
* word of the number, hex1 is a similar string for the next
* word, etc., and ndig is a parameters to g_ddfmt.
*/
#include "gdtoaimp.h"
#include <stdio.h>
#include <stdlib.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[1024];
#define U (unsigned long)
static void
#ifdef KR_headers
dprint(what, d) char *what; double d;
#else
dprint(char *what, double d)
#endif
{
char buf[32];
ULong *L = (ULong*)&d;
g_dfmt(buf,&d,0,sizeof(buf));
printf("%s = %s = #%lx %lx\n", what, buf, U L[_0], U L[_1]);
}
int
main(Void)
{
ULong *L;
char *s, *s1, *se, *se1;
int dItry, i, j, r = 1, ndig = 0;
double dd[2], ddI[4];
long LL[4];
L = (ULong*)&dd[0];
while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
while(*s <= ' ')
if (!*s++)
continue;
dItry = 0;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
LL[0] = L[_0];
LL[1] = L[_1];
LL[2] = L[2+_0];
LL[3] = L[2+_1];
sscanf(s+1, "%lx %lx %lx %lx", &LL[0], &LL[1],
&LL[2], &LL[3]);
L[_0] = LL[0];
L[_1] = LL[1];
L[2+_0] = LL[2];
L[2+_1] = LL[3];
printf("\nInput: %s", ibuf);
printf(" --> f = #%lx %lx %lx %lx\n",
LL[0],LL[1],LL[2],LL[3]);
goto fmt_test;
}
printf("\nInput: %s", ibuf);
for(s1 = s; *s1 > ' '; s1++){};
while(*s1 <= ' ' && *s1) s1++;
if (!*s1) {
dItry = 1;
i = strtordd(ibuf, &se, r, dd);
if (r == 1) {
j = strtopdd(ibuf, &se1, ddI);
if (i != j || dd[0] != ddI[0]
|| dd[1] != ddI[1] || se != se1)
printf("***strtopdd and strtordd disagree!!\n:");
}
printf("strtopdd consumes %d bytes and returns %d\n",
(int)(se-ibuf), i);
}
else {
dd[0] = strtod(s, &se);
dd[1] = strtod(se, &se);
}
fmt_test:
dprint("dd[0]", dd[0]);
dprint("dd[1]", dd[1]);
se = g_ddfmt(obuf, dd, ndig, sizeof(obuf));
printf("g_ddfmt(%d) gives %d bytes: \"%s\"\n\n",
ndig, (int)(se-obuf), se ? obuf : "<null>");
if (!dItry)
continue;
printf("strtoIdd returns %d,", strtoIdd(ibuf, &se, ddI,&ddI[2]));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (ddI[0] == ddI[2] && ddI[1] == ddI[3]) {
if (ddI[0] == dd[0] && ddI[1] == dd[1])
printf("ddI[0] == ddI[1] == strtopdd\n");
else
printf("ddI[0] == ddI[1] = #%lx %lx + %lx %lx\n= %.17g + %17.g\n",
U ((ULong*)ddI)[_0],
U ((ULong*)ddI)[_1],
U ((ULong*)ddI)[2+_0],
U ((ULong*)ddI)[2+_1],
ddI[0], ddI[1]);
}
else {
printf("ddI[0] = #%lx %lx + %lx %lx\n= %.17g + %.17g\n",
U ((ULong*)ddI)[_0], U ((ULong*)ddI)[_1],
U ((ULong*)ddI)[2+_0], U ((ULong*)ddI)[2+_1],
ddI[0], ddI[1]);
printf("ddI[1] = #%lx %lx + %lx %lx\n= %.17g + %.17g\n",
U ((ULong*)ddI)[4+_0], U ((ULong*)ddI)[4+_1],
U ((ULong*)ddI)[6+_0], U ((ULong*)ddI)[6+_1],
ddI[2], ddI[3]);
if (ddI[0] == dd[0] && ddI[1] == dd[1])
printf("ddI[0] == strtod\n");
else if (ddI[2] == dd[0] && ddI[3] == dd[1])
printf("ddI[1] == strtod\n");
else
printf("**** Both differ from strtopdd ****\n");
}
printf("\n");
}
return 0;
}

275
contrib/gdtoa/test/dt.c Normal file
View File

@ -0,0 +1,275 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for strtod and dtoa.
*
* Inputs (on stdin):
* number[: mode [ndigits]]
* or
* #hex0 hex1[: mode [ndigits]]
* where number is a decimal floating-point number,
* hex0 is a string of Hex digits for the most significant
* word of the number, hex1 is a similar string for the other
* (least significant) word, and mode and ndigits are
* parameters to dtoa.
*/
#include <stdio.h>
#include "gdtoa.h"
#ifdef KR_headers
#define Void /*void*/
#else
#define Void void
#endif
#ifdef __STDC__
#include <stdlib.h>
#else
#ifdef __cplusplus
extern "C" double atof(const char*);
#else
extern double atof ANSI((char*));
#endif
#endif
#ifdef IEEE_8087
#define word0(x) ((ULong *)&x)[1]
#define word1(x) ((ULong *)&x)[0]
#else
#define word0(x) ((ULong *)&x)[0]
#define word1(x) ((ULong *)&x)[1]
#endif
#include "errno.h"
#ifdef __cplusplus
extern "C" char *dtoa(double, int, int, int*, int*, char **);
#else
extern char *dtoa ANSI((double, int, int, int*, int*, char **));
#endif
static void
#ifdef KR_headers
g_fmt(b, x) char *b; double x;
#else
g_fmt(char *b, double x)
#endif
{
char *s, *se;
int decpt, i, j, k, sign;
if (!x) {
*b++ = '0';
*b = 0;
return;
}
s = dtoa(x, 0, 0, &decpt, &sign, &se);
if (sign)
*b++ = '-';
if (decpt == 9999) /* Infinity or Nan */ {
while(*b++ = *s++);
return;
}
if (decpt <= -4 || decpt > se - s + 5) {
*b++ = *s++;
if (*s) {
*b++ = '.';
while(*b = *s++)
b++;
}
*b++ = 'e';
/* sprintf(b, "%+.2d", decpt - 1); */
if (--decpt < 0) {
*b++ = '-';
decpt = -decpt;
}
else
*b++ = '+';
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){};
for(;;) {
i = decpt / k;
*b++ = i + '0';
if (--j <= 0)
break;
decpt -= i*k;
decpt *= 10;
}
*b = 0;
}
else if (decpt <= 0) {
*b++ = '.';
for(; decpt < 0; decpt++)
*b++ = '0';
while(*b++ = *s++);
}
else {
while(*b = *s++) {
b++;
if (--decpt == 0 && *s)
*b++ = '.';
}
for(; decpt > 0; decpt--)
*b++ = '0';
*b = 0;
}
}
static void
baderrno(Void)
{
fflush(stdout);
perror("\nerrno strtod");
fflush(stderr);
}
#define U (unsigned long)
static void
#ifdef KR_headers
check(d) double d;
#else
check(double d)
#endif
{
char buf[64];
int decpt, sign;
char *s, *se;
double d1;
s = dtoa(d, 0, 0, &decpt, &sign, &se);
sprintf(buf, "%s.%se%d", sign ? "-" : "", s, decpt);
errno = 0;
d1 = strtod(buf, (char **)0);
if (errno)
baderrno();
if (d != d1) {
printf("sent d = %.17g = 0x%lx %lx, buf = %s\n",
d, U word0(d), U word1(d), buf);
printf("got d1 = %.17g = 0x%lx %lx\n",
d1, U word0(d1), U word1(d1));
}
}
main(Void){
char buf[2048], buf1[32];
char *fmt, *s, *se;
double d, d1;
int decpt, sign;
int mode = 0, ndigits = 17;
ULong x, y;
#ifdef VAX
ULong z;
#endif
while(fgets(buf, sizeof(buf), stdin)) {
if (*buf == '*') {
printf("%s", buf);
continue;
}
printf("Input: %s", buf);
if (*buf == '#') {
x = word0(d);
y = word1(d);
sscanf(buf+1, "%lx %lx:%d %d", &x, &y, &mode, &ndigits);
word0(d) = x;
word1(d) = y;
fmt = "Output: d =\n%.17g = 0x%lx %lx\n";
}
else {
errno = 0;
d = strtod(buf,&se);
if (*se == ':')
sscanf(se+1,"%d %d", &mode, &ndigits);
d1 = atof(buf);
fmt = "Output: d =\n%.17g = 0x%lx %lx, se = %s";
if (errno)
baderrno();
}
printf(fmt, d, U word0(d), U word1(d), se);
g_fmt(buf1, d);
printf("\tg_fmt gives \"%s\"\n", buf1);
if (*buf != '#' && d != d1)
printf("atof gives\n\
d1 = %.17g = 0x%lx %lx\nversus\n\
d = %.17g = 0x%lx %lx\n", d1, U word0(d1), U word1(d1),
d, U word0(d), U word1(d));
check(d);
s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
printf("\tdtoa(mode = %d, ndigits = %d):\n", mode, ndigits);
printf("\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
sign, decpt, se-s, s);
x = word1(d);
if (x != 0xffffffff
&& (word0(d) & 0x7ff00000) != 0x7ff00000) {
#ifdef VAX
z = x << 16 | x >> 16;
z++;
z = z << 16 | z >> 16;
word1(d) = z;
#else
word1(d) = x + 1;
#endif
printf("\tnextafter(d,+Inf) = %.17g = 0x%lx %lx:\n",
d, U word0(d), U word1(d));
g_fmt(buf1, d);
printf("\tg_fmt gives \"%s\"\n", buf1);
s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
printf(
"\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
sign, decpt, se-s, s);
check(d);
}
if (x) {
#ifdef VAX
z = x << 16 | x >> 16;
z--;
z = z << 16 | z >> 16;
word1(d) = z;
#else
word1(d) = x - 1;
#endif
printf("\tnextafter(d,-Inf) = %.17g = 0x%lx %lx:\n",
d, U word0(d), U word1(d));
g_fmt(buf1, d);
printf("\tg_fmt gives \"%s\"\n", buf1);
s = dtoa(d, mode, ndigits, &decpt, &sign, &se);
printf(
"\tdtoa returns sign = %d, decpt = %d, %d digits:\n%s\n",
sign, decpt, se-s, s);
check(d);
}
}
return 0;
}

146
contrib/gdtoa/test/dtest.c Normal file
View File

@ -0,0 +1,146 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_dfmt, strtoId, strtod, strtopd, and strtord.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex0 hex1
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex0 is a string of Hex <= 8 digits for the most significant
* word of the number, hex1 is a similar string for the other
* (least significant) word, and ndig is a parameters to g_dfmt.
*/
#include "gdtoaimp.h"
#include <stdio.h>
#include <stdlib.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[1024];
#define U (unsigned long)
int
main(Void)
{
ULong *L;
char *s, *se, *se1;
double f, f1, fI[2];
int i, i1, ndig = 0, r = 1;
long LL[2];
L = (ULong*)&f;
while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
while(*s <= ' ')
if (!*s++)
continue;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
LL[0] = L[_0];
LL[1] = L[_1];
sscanf(s+1, "%lx %lx", &LL[0], &LL[1]);
L[_0] = LL[0];
L[_1] = LL[1];
printf("\nInput: %s", ibuf);
printf("--> f = #%lx %lx\n", (long)L[_0], (long)L[_1]);
goto fmt_test;
}
printf("\nInput: %s", ibuf);
i = strtord(ibuf, &se, r, &f);
if (r == 1) {
if ((f != strtod(ibuf, &se1) || se1 != se))
printf("***strtod and strtord disagree!!\n");
i1 = strtopd(ibuf, &se, &f1);
if (i != i1 || f != f1 || se != se1)
printf("***strtord and strtopd disagree!!\n");
}
printf("strtod consumes %d bytes and returns %d with f = %.17g = #%lx %lx\n",
(int)(se-ibuf), i, f, U L[_0], U L[_1]);
fmt_test:
se = g_dfmt(obuf, &f, ndig, sizeof(obuf));
printf("g_dfmt(%d) gives %d bytes: \"%s\"\n\n",
ndig, (int)(se-obuf), se ? obuf : "<null>");
if (*s == '#')
continue;
printf("strtoId returns %d,", strtoId(ibuf, &se, fI, &fI[1]));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (fI[0] == fI[1]) {
if (fI[0] == f)
printf("fI[0] == fI[1] == strtod\n");
else
printf("fI[0] == fI[1] = #%lx %lx = %.17g\n",
U ((ULong*)fI)[_0], U ((ULong*)fI)[_1],
fI[0]);
}
else {
printf("fI[0] = #%lx %lx = %.17g\n",
U ((ULong*)fI)[_0], U ((ULong*)fI)[_1], fI[0]);
printf("fI[1] = #%lx %lx = %.17g\n",
U ((ULong*)&fI[1])[_0], U ((ULong*)&fI[1])[_1],
fI[1]);
if (fI[0] == f)
printf("fI[0] == strtod\n");
else if (fI[1] == f)
printf("fI[1] == strtod\n");
else
printf("**** Both differ from strtod ****\n");
}
printf("\n");
}
return 0;
}

686
contrib/gdtoa/test/dtst.out Normal file
View File

@ -0,0 +1,686 @@
Input: 1.23
Output: d =
1.23 = 0x3ff3ae14 7ae147ae, se =
g_fmt gives "1.23"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 1, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af:
g_fmt gives "1.2300000000000002"
dtoa returns sign = 0, decpt = 1, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad:
g_fmt gives "1.2299999999999998"
dtoa returns sign = 0, decpt = 1, 17 digits:
12299999999999998
Input: 1.23e+20
Output: d =
1.23e+20 = 0x441aabdf 2145b430, se =
g_fmt gives "1.23e+20"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 21, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431:
g_fmt gives "123000000000000020000"
dtoa returns sign = 0, decpt = 21, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f:
g_fmt gives "122999999999999980000"
dtoa returns sign = 0, decpt = 21, 17 digits:
12299999999999998
Input: 1.23e-20
Output: d =
1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se =
g_fmt gives "1.23e-20"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532:
g_fmt gives "1.2300000000000002e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530:
g_fmt gives "1.2299999999999999e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12299999999999999
Input: 1.23456789
Output: d =
1.2345678899999999 = 0x3ff3c0ca 4283de1b, se =
g_fmt gives "1.23456789"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 1, 9 digits:
123456789
nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c:
g_fmt gives "1.2345678900000001"
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678900000001
nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a:
g_fmt gives "1.2345678899999997"
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678899999997
Input: 1.23456589e+20
Output: d =
1.23456589e+20 = 0x441ac537 a660b997, se =
g_fmt gives "1.23456589e+20"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 21, 9 digits:
123456589
nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998:
g_fmt gives "123456589000000010000"
dtoa returns sign = 0, decpt = 21, 17 digits:
12345658900000001
nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996:
g_fmt gives "123456588999999980000"
dtoa returns sign = 0, decpt = 21, 17 digits:
12345658899999998
Input: 1.23e+30
Output: d =
1.23e+30 = 0x462f0cb0 4e8fb790, se =
g_fmt gives "1.23e+30"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 31, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000001e+30 = 0x462f0cb0 4e8fb791:
g_fmt gives "1.2300000000000001e+30"
dtoa returns sign = 0, decpt = 31, 17 digits:
12300000000000001
nextafter(d,-Inf) = 1.2299999999999998e+30 = 0x462f0cb0 4e8fb78f:
g_fmt gives "1.2299999999999998e+30"
dtoa returns sign = 0, decpt = 31, 17 digits:
12299999999999998
Input: 1.23e-30
Output: d =
1.2300000000000001e-30 = 0x39b8f286 6f5010ab, se =
g_fmt gives "1.23e-30"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -29, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-30 = 0x39b8f286 6f5010ac:
g_fmt gives "1.2300000000000002e-30"
dtoa returns sign = 0, decpt = -29, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999999e-30 = 0x39b8f286 6f5010aa:
g_fmt gives "1.2299999999999999e-30"
dtoa returns sign = 0, decpt = -29, 17 digits:
12299999999999999
Input: 1.23456789e-20
Output: d =
1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se =
g_fmt gives "1.23456789e-20"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -19, 9 digits:
123456789
nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb:
g_fmt gives "1.2345678900000001e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12345678900000001
nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9:
g_fmt gives "1.2345678899999998e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12345678899999998
Input: 1.23456789e-30
Output: d =
1.23456789e-30 = 0x39b90a3e 33bbd995, se =
g_fmt gives "1.23456789e-30"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -29, 9 digits:
123456789
nextafter(d,+Inf) = 1.2345678900000002e-30 = 0x39b90a3e 33bbd996:
g_fmt gives "1.2345678900000002e-30"
dtoa returns sign = 0, decpt = -29, 17 digits:
12345678900000002
nextafter(d,-Inf) = 1.2345678899999998e-30 = 0x39b90a3e 33bbd994:
g_fmt gives "1.2345678899999998e-30"
dtoa returns sign = 0, decpt = -29, 17 digits:
12345678899999998
Input: 1.234567890123456789
Output: d =
1.2345678901234567 = 0x3ff3c0ca 428c59fb, se =
g_fmt gives "1.2345678901234567"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234567
nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc:
g_fmt gives "1.234567890123457"
dtoa returns sign = 0, decpt = 1, 16 digits:
1234567890123457
nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa:
g_fmt gives "1.2345678901234565"
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234565
Input: 1.23456789012345678901234567890123456789
Output: d =
1.2345678901234567 = 0x3ff3c0ca 428c59fb, se =
g_fmt gives "1.2345678901234567"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234567
nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc:
g_fmt gives "1.234567890123457"
dtoa returns sign = 0, decpt = 1, 16 digits:
1234567890123457
nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa:
g_fmt gives "1.2345678901234565"
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234565
Input: 1.23e306
Output: d =
1.23e+306 = 0x7f7c0676 cd1c61f5, se =
g_fmt gives "1.23e+306"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 307, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e+306 = 0x7f7c0676 cd1c61f6:
g_fmt gives "1.2300000000000002e+306"
dtoa returns sign = 0, decpt = 307, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999999e+306 = 0x7f7c0676 cd1c61f4:
g_fmt gives "1.2299999999999999e+306"
dtoa returns sign = 0, decpt = 307, 17 digits:
12299999999999999
Input: 1.23e-306
Output: d =
1.23e-306 = 0x6ba3b8 5da396e8, se =
g_fmt gives "1.23e-306"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -305, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-306 = 0x6ba3b8 5da396e9:
g_fmt gives "1.2300000000000002e-306"
dtoa returns sign = 0, decpt = -305, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999999e-306 = 0x6ba3b8 5da396e7:
g_fmt gives "1.2299999999999999e-306"
dtoa returns sign = 0, decpt = -305, 17 digits:
12299999999999999
Input: 1.23e-320
Output: d =
1.2302234581447039e-320 = 0x0 9ba, se =
g_fmt gives "1.23e-320"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -319, 3 digits:
123
nextafter(d,+Inf) = 1.2307175237905451e-320 = 0x0 9bb:
g_fmt gives "1.2307e-320"
dtoa returns sign = 0, decpt = -319, 5 digits:
12307
nextafter(d,-Inf) = 1.2297293924988626e-320 = 0x0 9b9:
g_fmt gives "1.2297e-320"
dtoa returns sign = 0, decpt = -319, 5 digits:
12297
Input: 1.23e-20
Output: d =
1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se =
g_fmt gives "1.23e-20"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532:
g_fmt gives "1.2300000000000002e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12300000000000002
nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530:
g_fmt gives "1.2299999999999999e-20"
dtoa returns sign = 0, decpt = -19, 17 digits:
12299999999999999
Input: 1.23456789e307
Output: d =
1.23456789e+307 = 0x7fb194b1 4bdaecdc, se =
g_fmt gives "1.23456789e+307"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 308, 9 digits:
123456789
nextafter(d,+Inf) = 1.2345678900000003e+307 = 0x7fb194b1 4bdaecdd:
g_fmt gives "1.2345678900000003e+307"
dtoa returns sign = 0, decpt = 308, 17 digits:
12345678900000003
nextafter(d,-Inf) = 1.2345678899999998e+307 = 0x7fb194b1 4bdaecdb:
g_fmt gives "1.2345678899999998e+307"
dtoa returns sign = 0, decpt = 308, 17 digits:
12345678899999998
Input: 1.23456589e-307
Output: d =
1.2345658899999999e-307 = 0x363196 bb9845fa, se =
g_fmt gives "1.23456589e-307"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -306, 9 digits:
123456589
nextafter(d,+Inf) = 1.2345658900000001e-307 = 0x363196 bb9845fb:
g_fmt gives "1.2345658900000001e-307"
dtoa returns sign = 0, decpt = -306, 17 digits:
12345658900000001
nextafter(d,-Inf) = 1.2345658899999997e-307 = 0x363196 bb9845f9:
g_fmt gives "1.2345658899999997e-307"
dtoa returns sign = 0, decpt = -306, 17 digits:
12345658899999997
Input: 1.234567890123456789
Output: d =
1.2345678901234567 = 0x3ff3c0ca 428c59fb, se =
g_fmt gives "1.2345678901234567"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234567
nextafter(d,+Inf) = 1.2345678901234569 = 0x3ff3c0ca 428c59fc:
g_fmt gives "1.234567890123457"
dtoa returns sign = 0, decpt = 1, 16 digits:
1234567890123457
nextafter(d,-Inf) = 1.2345678901234565 = 0x3ff3c0ca 428c59fa:
g_fmt gives "1.2345678901234565"
dtoa returns sign = 0, decpt = 1, 17 digits:
12345678901234565
Input: 1.234567890123456789e301
Output: d =
1.2345678901234568e+301 = 0x7e726f51 75f56413, se =
g_fmt gives "1.2345678901234568e+301"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 302, 17 digits:
12345678901234568
nextafter(d,+Inf) = 1.234567890123457e+301 = 0x7e726f51 75f56414:
g_fmt gives "1.234567890123457e+301"
dtoa returns sign = 0, decpt = 302, 16 digits:
1234567890123457
nextafter(d,-Inf) = 1.2345678901234565e+301 = 0x7e726f51 75f56412:
g_fmt gives "1.2345678901234565e+301"
dtoa returns sign = 0, decpt = 302, 17 digits:
12345678901234565
Input: 1.234567890123456789e-301
Output: d =
1.2345678901234567e-301 = 0x1752a64 e34ba0d3, se =
g_fmt gives "1.2345678901234567e-301"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -300, 17 digits:
12345678901234567
nextafter(d,+Inf) = 1.2345678901234569e-301 = 0x1752a64 e34ba0d4:
g_fmt gives "1.234567890123457e-301"
dtoa returns sign = 0, decpt = -300, 16 digits:
1234567890123457
nextafter(d,-Inf) = 1.2345678901234565e-301 = 0x1752a64 e34ba0d2:
g_fmt gives "1.2345678901234565e-301"
dtoa returns sign = 0, decpt = -300, 17 digits:
12345678901234565
Input: 1.234567890123456789e-321
Output: d =
1.2351641146031164e-321 = 0x0 fa, se =
g_fmt gives "1.235e-321"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -320, 4 digits:
1235
nextafter(d,+Inf) = 1.2401047710615288e-321 = 0x0 fb:
g_fmt gives "1.24e-321"
dtoa returns sign = 0, decpt = -320, 3 digits:
124
nextafter(d,-Inf) = 1.2302234581447039e-321 = 0x0 f9:
g_fmt gives "1.23e-321"
dtoa returns sign = 0, decpt = -320, 3 digits:
123
Input: 1e23
Output: d =
9.9999999999999992e+22 = 0x44b52d02 c7e14af6, se =
g_fmt gives "1e+23"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 24, 1 digits:
1
nextafter(d,+Inf) = 1.0000000000000001e+23 = 0x44b52d02 c7e14af7:
g_fmt gives "1.0000000000000001e+23"
dtoa returns sign = 0, decpt = 24, 17 digits:
10000000000000001
nextafter(d,-Inf) = 9.9999999999999975e+22 = 0x44b52d02 c7e14af5:
g_fmt gives "9.999999999999997e+22"
dtoa returns sign = 0, decpt = 23, 16 digits:
9999999999999997
Input: 1e310
errno strtod: Result too large
Output: d =
Infinity = 0x7ff00000 0, se =
g_fmt gives "Infinity"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = 9999, 8 digits:
Infinity
Input: 9.0259718793241475e-277
Output: d =
9.0259718793241479e-277 = 0x6a00000 0, se =
g_fmt gives "9.025971879324148e-277"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -276, 16 digits:
9025971879324148
nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1:
g_fmt gives "9.02597187932415e-277"
dtoa returns sign = 0, decpt = -276, 15 digits:
902597187932415
Input: 9.025971879324147880346310405869e-277
Output: d =
9.0259718793241479e-277 = 0x6a00000 0, se =
g_fmt gives "9.025971879324148e-277"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -276, 16 digits:
9025971879324148
nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1:
g_fmt gives "9.02597187932415e-277"
dtoa returns sign = 0, decpt = -276, 15 digits:
902597187932415
Input: 9.025971879324147880346310405868e-277
Output: d =
9.0259718793241479e-277 = 0x6a00000 0, se =
g_fmt gives "9.025971879324148e-277"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -276, 16 digits:
9025971879324148
nextafter(d,+Inf) = 9.0259718793241499e-277 = 0x6a00000 1:
g_fmt gives "9.02597187932415e-277"
dtoa returns sign = 0, decpt = -276, 15 digits:
902597187932415
Input: 2.2250738585072014e-308
Output: d =
2.2250738585072014e-308 = 0x100000 0, se =
g_fmt gives "2.2250738585072014e-308"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -307, 17 digits:
22250738585072014
nextafter(d,+Inf) = 2.2250738585072019e-308 = 0x100000 1:
g_fmt gives "2.225073858507202e-308"
dtoa returns sign = 0, decpt = -307, 16 digits:
2225073858507202
Input: 2.2250738585072013e-308
Output: d =
2.2250738585072014e-308 = 0x100000 0, se =
g_fmt gives "2.2250738585072014e-308"
dtoa(mode = 0, ndigits = 17):
dtoa returns sign = 0, decpt = -307, 17 digits:
22250738585072014
nextafter(d,+Inf) = 2.2250738585072019e-308 = 0x100000 1:
g_fmt gives "2.225073858507202e-308"
dtoa returns sign = 0, decpt = -307, 16 digits:
2225073858507202
Input: 1.23:2 6
Output: d =
1.23 = 0x3ff3ae14 7ae147ae, se = :2 6
g_fmt gives "1.23"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af:
g_fmt gives "1.2300000000000002"
dtoa returns sign = 0, decpt = 1, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad:
g_fmt gives "1.2299999999999998"
dtoa returns sign = 0, decpt = 1, 3 digits:
123
Input: 1.23:4 6
Output: d =
1.23 = 0x3ff3ae14 7ae147ae, se = :4 6
g_fmt gives "1.23"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002 = 0x3ff3ae14 7ae147af:
g_fmt gives "1.2300000000000002"
dtoa returns sign = 0, decpt = 1, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999998 = 0x3ff3ae14 7ae147ad:
g_fmt gives "1.2299999999999998"
dtoa returns sign = 0, decpt = 1, 3 digits:
123
Input: 1.23e+20:2 6
Output: d =
1.23e+20 = 0x441aabdf 2145b430, se = :2 6
g_fmt gives "1.23e+20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431:
g_fmt gives "123000000000000020000"
dtoa returns sign = 0, decpt = 21, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f:
g_fmt gives "122999999999999980000"
dtoa returns sign = 0, decpt = 21, 3 digits:
123
Input: 1.23e+20:4 6
Output: d =
1.23e+20 = 0x441aabdf 2145b430, se = :4 6
g_fmt gives "1.23e+20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e+20 = 0x441aabdf 2145b431:
g_fmt gives "123000000000000020000"
dtoa returns sign = 0, decpt = 21, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999998e+20 = 0x441aabdf 2145b42f:
g_fmt gives "122999999999999980000"
dtoa returns sign = 0, decpt = 21, 3 digits:
123
Input: 1.23e-20:2 6
Output: d =
1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = :2 6
g_fmt gives "1.23e-20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532:
g_fmt gives "1.2300000000000002e-20"
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530:
g_fmt gives "1.2299999999999999e-20"
dtoa returns sign = 0, decpt = -19, 3 digits:
123
Input: 1.23e-20:4 6
Output: d =
1.2300000000000001e-20 = 0x3bcd0ae4 cf767531, se = :4 6
g_fmt gives "1.23e-20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,+Inf) = 1.2300000000000002e-20 = 0x3bcd0ae4 cf767532:
g_fmt gives "1.2300000000000002e-20"
dtoa returns sign = 0, decpt = -19, 3 digits:
123
nextafter(d,-Inf) = 1.2299999999999999e-20 = 0x3bcd0ae4 cf767530:
g_fmt gives "1.2299999999999999e-20"
dtoa returns sign = 0, decpt = -19, 3 digits:
123
Input: 1.23456789:2 6
Output: d =
1.2345678899999999 = 0x3ff3c0ca 4283de1b, se = :2 6
g_fmt gives "1.23456789"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c:
g_fmt gives "1.2345678900000001"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a:
g_fmt gives "1.2345678899999997"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
Input: 1.23456789:4 6
Output: d =
1.2345678899999999 = 0x3ff3c0ca 4283de1b, se = :4 6
g_fmt gives "1.23456789"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,+Inf) = 1.2345678900000001 = 0x3ff3c0ca 4283de1c:
g_fmt gives "1.2345678900000001"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,-Inf) = 1.2345678899999997 = 0x3ff3c0ca 4283de1a:
g_fmt gives "1.2345678899999997"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
Input: 1.23456589e+20:2 6
Output: d =
1.23456589e+20 = 0x441ac537 a660b997, se = :2 6
g_fmt gives "1.23456589e+20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998:
g_fmt gives "123456589000000010000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996:
g_fmt gives "123456588999999980000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
Input: 1.23456589e+20:4 6
Output: d =
1.23456589e+20 = 0x441ac537 a660b997, se = :4 6
g_fmt gives "1.23456589e+20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,+Inf) = 1.2345658900000001e+20 = 0x441ac537 a660b998:
g_fmt gives "123456589000000010000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,-Inf) = 1.2345658899999998e+20 = 0x441ac537 a660b996:
g_fmt gives "123456588999999980000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
Input: 1.23456789e-20:2 6
Output: d =
1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se = :2 6
g_fmt gives "1.23456789e-20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb:
g_fmt gives "1.2345678900000001e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9:
g_fmt gives "1.2345678899999998e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
Input: 1.23456789e-20:4 6
Output: d =
1.2345678899999999e-20 = 0x3bcd2681 471e7ada, se = :4 6
g_fmt gives "1.23456789e-20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,+Inf) = 1.2345678900000001e-20 = 0x3bcd2681 471e7adb:
g_fmt gives "1.2345678900000001e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,-Inf) = 1.2345678899999998e-20 = 0x3bcd2681 471e7ad9:
g_fmt gives "1.2345678899999998e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
Input: 1234565:2 6
Output: d =
1234565 = 0x4132d685 0, se = :2 6
g_fmt gives "1234565"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 7, 6 digits:
123456
nextafter(d,+Inf) = 1234565.0000000002 = 0x4132d685 1:
g_fmt gives "1234565.0000000002"
dtoa returns sign = 0, decpt = 7, 6 digits:
123457
Input: 1234565:4 6
Output: d =
1234565 = 0x4132d685 0, se = :4 6
g_fmt gives "1234565"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 7, 6 digits:
123456
nextafter(d,+Inf) = 1234565.0000000002 = 0x4132d685 1:
g_fmt gives "1234565.0000000002"
dtoa returns sign = 0, decpt = 7, 6 digits:
123457
Input: 1.234565:2 6
Output: d =
1.2345649999999999 = 0x3ff3c0c7 3abc9470, se = :2 6
g_fmt gives "1.234565"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000001 = 0x3ff3c0c7 3abc9471:
g_fmt gives "1.2345650000000001"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999997 = 0x3ff3c0c7 3abc946f:
g_fmt gives "1.2345649999999997"
dtoa returns sign = 0, decpt = 1, 6 digits:
123456
Input: 1.234565:4 6
Output: d =
1.2345649999999999 = 0x3ff3c0c7 3abc9470, se = :4 6
g_fmt gives "1.234565"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 1, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000001 = 0x3ff3c0c7 3abc9471:
g_fmt gives "1.2345650000000001"
dtoa returns sign = 0, decpt = 1, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999997 = 0x3ff3c0c7 3abc946f:
g_fmt gives "1.2345649999999997"
dtoa returns sign = 0, decpt = 1, 6 digits:
123456
Input: 1.234565e+20:2 6
Output: d =
1.234565e+20 = 0x441ac536 6299040d, se = :2 6
g_fmt gives "1.234565e+20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000002e+20 = 0x441ac536 6299040e:
g_fmt gives "123456500000000020000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999998e+20 = 0x441ac536 6299040c:
g_fmt gives "123456499999999980000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123456
Input: 1.234565e+20:4 6
Output: d =
1.234565e+20 = 0x441ac536 6299040d, se = :4 6
g_fmt gives "1.234565e+20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = 21, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000002e+20 = 0x441ac536 6299040e:
g_fmt gives "123456500000000020000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999998e+20 = 0x441ac536 6299040c:
g_fmt gives "123456499999999980000"
dtoa returns sign = 0, decpt = 21, 6 digits:
123456
Input: 1.234565e-20:2 6
Output: d =
1.234565e-20 = 0x3bcd267c ce45a93f, se = :2 6
g_fmt gives "1.234565e-20"
dtoa(mode = 2, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000001e-20 = 0x3bcd267c ce45a940:
g_fmt gives "1.2345650000000001e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999998e-20 = 0x3bcd267c ce45a93e:
g_fmt gives "1.2345649999999998e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123456
Input: 1.234565e-20:4 6
Output: d =
1.234565e-20 = 0x3bcd267c ce45a93f, se = :4 6
g_fmt gives "1.234565e-20"
dtoa(mode = 4, ndigits = 6):
dtoa returns sign = 0, decpt = -19, 6 digits:
123456
nextafter(d,+Inf) = 1.2345650000000001e-20 = 0x3bcd267c ce45a940:
g_fmt gives "1.2345650000000001e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123457
nextafter(d,-Inf) = 1.2345649999999998e-20 = 0x3bcd267c ce45a93e:
g_fmt gives "1.2345649999999998e-20"
dtoa returns sign = 0, decpt = -19, 6 digits:
123456

968
contrib/gdtoa/test/f.out Normal file
View File

@ -0,0 +1,968 @@
Input: 1.23
strtof consumes 4 bytes and returns 1.23 = #3f9d70a4
g_ffmt(0) gives 4 bytes: "1.23"
strtoIf returns 33, consuming 4 bytes.
fI[0] = #3f9d70a3 = 1.2299999
fI[1] = #3f9d70a4 = 1.23
fI[1] == strtof
Input: 1.23e+20
strtof consumes 8 bytes and returns 1.23e+20 = #60d55ef9
g_ffmt(0) gives 8 bytes: "1.23e+20"
strtoIf returns 17, consuming 8 bytes.
fI[0] = #60d55ef9 = 1.23e+20
fI[1] = #60d55efa = 1.2300001e+20
fI[0] == strtof
Input: 1.23e-20
strtof consumes 8 bytes and returns 1.23e-20 = #1e685726
g_ffmt(0) gives 8 bytes: "1.23e-20"
strtoIf returns 17, consuming 8 bytes.
fI[0] = #1e685726 = 1.23e-20
fI[1] = #1e685727 = 1.23e-20
fI[0] == strtof
Input: 1.23456789
strtof consumes 10 bytes and returns 1.2345679 = #3f9e0652
g_ffmt(0) gives 9 bytes: "1.2345679"
strtoIf returns 17, consuming 10 bytes.
fI[0] = #3f9e0652 = 1.2345679
fI[1] = #3f9e0653 = 1.234568
fI[0] == strtof
Input: 1.23456589e+20
strtof consumes 14 bytes and returns 1.2345659e+20 = #60d629bd
g_ffmt(0) gives 13 bytes: "1.2345659e+20"
strtoIf returns 17, consuming 14 bytes.
fI[0] = #60d629bd = 1.2345659e+20
fI[1] = #60d629be = 1.234566e+20
fI[0] == strtof
Input: 1.23e+30
strtof consumes 8 bytes and returns 1.23e+30 = #71786582
g_ffmt(0) gives 8 bytes: "1.23e+30"
strtoIf returns 17, consuming 8 bytes.
fI[0] = #71786582 = 1.23e+30
fI[1] = #71786583 = 1.23e+30
fI[0] == strtof
Input: 1.23e-30
strtof consumes 8 bytes and returns 1.23e-30 = #dc79433
g_ffmt(0) gives 8 bytes: "1.23e-30"
strtoIf returns 17, consuming 8 bytes.
fI[0] = #dc79433 = 1.23e-30
fI[1] = #dc79434 = 1.23e-30
fI[0] == strtof
Input: 1.23456789e-20
strtof consumes 14 bytes and returns 1.2345679e-20 = #1e69340a
g_ffmt(0) gives 13 bytes: "1.2345679e-20"
strtoIf returns 17, consuming 14 bytes.
fI[0] = #1e69340a = 1.2345679e-20
fI[1] = #1e69340b = 1.234568e-20
fI[0] == strtof
Input: 1.23456789e-30
strtof consumes 14 bytes and returns 1.2345679e-30 = #dc851f2
g_ffmt(0) gives 13 bytes: "1.2345679e-30"
strtoIf returns 33, consuming 14 bytes.
fI[0] = #dc851f1 = 1.2345678e-30
fI[1] = #dc851f2 = 1.2345679e-30
fI[1] == strtof
Input: 1.234567890123456789
strtof consumes 20 bytes and returns 1.2345679 = #3f9e0652
g_ffmt(0) gives 9 bytes: "1.2345679"
strtoIf returns 17, consuming 20 bytes.
fI[0] = #3f9e0652 = 1.2345679
fI[1] = #3f9e0653 = 1.234568
fI[0] == strtof
Input: 1.23456789012345678901234567890123456789
strtof consumes 40 bytes and returns 1.2345679 = #3f9e0652
g_ffmt(0) gives 9 bytes: "1.2345679"
strtoIf returns 17, consuming 40 bytes.
fI[0] = #3f9e0652 = 1.2345679
fI[1] = #3f9e0653 = 1.234568
fI[0] == strtof
Input: 1.23e306
strtof consumes 8 bytes and returns Infinity = #7f800000
g_ffmt(0) gives 8 bytes: "Infinity"
strtoIf returns 163, consuming 8 bytes.
fI[0] = #7f7fffff = 3.4028235e+38
fI[1] = #7f800000 = Infinity
fI[1] == strtof
Input: 1.23e-306
strtof consumes 9 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 9 bytes.
fI[0] == fI[1] == strtof
Input: 1.23e-320
strtof consumes 9 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 9 bytes.
fI[0] == fI[1] == strtof
Input: 1.23e-20
strtof consumes 8 bytes and returns 1.23e-20 = #1e685726
g_ffmt(0) gives 8 bytes: "1.23e-20"
strtoIf returns 17, consuming 8 bytes.
fI[0] = #1e685726 = 1.23e-20
fI[1] = #1e685727 = 1.23e-20
fI[0] == strtof
Input: 1.23456789e307
strtof consumes 14 bytes and returns Infinity = #7f800000
g_ffmt(0) gives 8 bytes: "Infinity"
strtoIf returns 163, consuming 14 bytes.
fI[0] = #7f7fffff = 3.4028235e+38
fI[1] = #7f800000 = Infinity
fI[1] == strtof
Input: 1.23456589e-307
strtof consumes 15 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 15 bytes.
fI[0] == fI[1] == strtof
Input: 1.234567890123456789
strtof consumes 20 bytes and returns 1.2345679 = #3f9e0652
g_ffmt(0) gives 9 bytes: "1.2345679"
strtoIf returns 17, consuming 20 bytes.
fI[0] = #3f9e0652 = 1.2345679
fI[1] = #3f9e0653 = 1.234568
fI[0] == strtof
Input: 1.234567890123456789e301
strtof consumes 24 bytes and returns Infinity = #7f800000
g_ffmt(0) gives 8 bytes: "Infinity"
strtoIf returns 163, consuming 24 bytes.
fI[0] = #7f7fffff = 3.4028235e+38
fI[1] = #7f800000 = Infinity
fI[1] == strtof
Input: 1.234567890123456789e-301
strtof consumes 25 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 25 bytes.
fI[0] == fI[1] == strtof
Input: 1.234567890123456789e-321
strtof consumes 25 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 25 bytes.
fI[0] == fI[1] == strtof
Input: 1e23
strtof consumes 4 bytes and returns 9.9999998e+22 = #65a96816
g_ffmt(0) gives 5 bytes: "1e+23"
strtoIf returns 17, consuming 4 bytes.
fI[0] = #65a96816 = 9.9999998e+22
fI[1] = #65a96817 = 1.0000001e+23
fI[0] == strtof
Input: 1e310
strtof consumes 5 bytes and returns Infinity = #7f800000
g_ffmt(0) gives 8 bytes: "Infinity"
strtoIf returns 163, consuming 5 bytes.
fI[0] = #7f7fffff = 3.4028235e+38
fI[1] = #7f800000 = Infinity
fI[1] == strtof
Input: 9.0259718793241475e-277
strtof consumes 23 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 23 bytes.
fI[0] == fI[1] == strtof
Input: 9.025971879324147880346310405869e-277
strtof consumes 37 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 37 bytes.
fI[0] == fI[1] == strtof
Input: 9.025971879324147880346310405868e-277
strtof consumes 37 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 37 bytes.
fI[0] == fI[1] == strtof
Input: 2.2250738585072014e-308
strtof consumes 23 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 23 bytes.
fI[0] == fI[1] == strtof
Input: 2.2250738585072013e-308
strtof consumes 23 bytes and returns 0 = #0
g_ffmt(0) gives 1 bytes: "0"
strtoIf returns 80, consuming 23 bytes.
fI[0] == fI[1] == strtof
Rounding mode for strtor... changed from 1 (nearest) to 0 (toward zero)
Input: 1.1
strtof consumes 3 bytes and returns 1.0999999 = #3f8ccccc
g_ffmt(0) gives 9 bytes: "1.0999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f8ccccc = 1.0999999
fI[1] = #3f8ccccd = 1.1
fI[0] == strtof
Input: -1.1
strtof consumes 4 bytes and returns -1.0999999 = #bf8ccccc
g_ffmt(0) gives 10 bytes: "-1.0999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf8ccccd = -1.1
fI[1] = #bf8ccccc = -1.0999999
fI[1] == strtof
Input: 1.2
strtof consumes 3 bytes and returns 1.1999999 = #3f999999
g_ffmt(0) gives 9 bytes: "1.1999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f999999 = 1.1999999
fI[1] = #3f99999a = 1.2
fI[0] == strtof
Input: -1.2
strtof consumes 4 bytes and returns -1.1999999 = #bf999999
g_ffmt(0) gives 10 bytes: "-1.1999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf99999a = -1.2
fI[1] = #bf999999 = -1.1999999
fI[1] == strtof
Input: 1.3
strtof consumes 3 bytes and returns 1.3 = #3fa66666
g_ffmt(0) gives 3 bytes: "1.3"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fa66666 = 1.3
fI[1] = #3fa66667 = 1.3000001
fI[0] == strtof
Input: -1.3
strtof consumes 4 bytes and returns -1.3 = #bfa66666
g_ffmt(0) gives 4 bytes: "-1.3"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfa66667 = -1.3000001
fI[1] = #bfa66666 = -1.3
fI[1] == strtof
Input: 1.4
strtof consumes 3 bytes and returns 1.4 = #3fb33333
g_ffmt(0) gives 3 bytes: "1.4"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fb33333 = 1.4
fI[1] = #3fb33334 = 1.4000001
fI[0] == strtof
Input: -1.4
strtof consumes 4 bytes and returns -1.4 = #bfb33333
g_ffmt(0) gives 4 bytes: "-1.4"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfb33334 = -1.4000001
fI[1] = #bfb33333 = -1.4
fI[1] == strtof
Input: 1.5
strtof consumes 3 bytes and returns 1.5 = #3fc00000
g_ffmt(0) gives 3 bytes: "1.5"
strtoIf returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtof
Input: -1.5
strtof consumes 4 bytes and returns -1.5 = #bfc00000
g_ffmt(0) gives 4 bytes: "-1.5"
strtoIf returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtof
Input: 1.6
strtof consumes 3 bytes and returns 1.5999999 = #3fcccccc
g_ffmt(0) gives 9 bytes: "1.5999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fcccccc = 1.5999999
fI[1] = #3fcccccd = 1.6
fI[0] == strtof
Input: -1.6
strtof consumes 4 bytes and returns -1.5999999 = #bfcccccc
g_ffmt(0) gives 10 bytes: "-1.5999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfcccccd = -1.6
fI[1] = #bfcccccc = -1.5999999
fI[1] == strtof
Input: 1.7
strtof consumes 3 bytes and returns 1.6999999 = #3fd99999
g_ffmt(0) gives 9 bytes: "1.6999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fd99999 = 1.6999999
fI[1] = #3fd9999a = 1.7
fI[0] == strtof
Input: -1.7
strtof consumes 4 bytes and returns -1.6999999 = #bfd99999
g_ffmt(0) gives 10 bytes: "-1.6999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfd9999a = -1.7
fI[1] = #bfd99999 = -1.6999999
fI[1] == strtof
Input: 1.8
strtof consumes 3 bytes and returns 1.8 = #3fe66666
g_ffmt(0) gives 3 bytes: "1.8"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fe66666 = 1.8
fI[1] = #3fe66667 = 1.8000001
fI[0] == strtof
Input: -1.8
strtof consumes 4 bytes and returns -1.8 = #bfe66666
g_ffmt(0) gives 4 bytes: "-1.8"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfe66667 = -1.8000001
fI[1] = #bfe66666 = -1.8
fI[1] == strtof
Input: 1.9
strtof consumes 3 bytes and returns 1.9 = #3ff33333
g_ffmt(0) gives 3 bytes: "1.9"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3ff33333 = 1.9
fI[1] = #3ff33334 = 1.9000001
fI[0] == strtof
Input: -1.9
strtof consumes 4 bytes and returns -1.9 = #bff33333
g_ffmt(0) gives 4 bytes: "-1.9"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bff33334 = -1.9000001
fI[1] = #bff33333 = -1.9
fI[1] == strtof
Rounding mode for strtor... changed from 0 (toward zero) to 1 (nearest)
Input: 1.1
strtof consumes 3 bytes and returns 1.1 = #3f8ccccd
g_ffmt(0) gives 3 bytes: "1.1"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f8ccccc = 1.0999999
fI[1] = #3f8ccccd = 1.1
fI[1] == strtof
Input: -1.1
strtof consumes 4 bytes and returns -1.1 = #bf8ccccd
g_ffmt(0) gives 4 bytes: "-1.1"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf8ccccd = -1.1
fI[1] = #bf8ccccc = -1.0999999
fI[0] == strtof
Input: 1.2
strtof consumes 3 bytes and returns 1.2 = #3f99999a
g_ffmt(0) gives 3 bytes: "1.2"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f999999 = 1.1999999
fI[1] = #3f99999a = 1.2
fI[1] == strtof
Input: -1.2
strtof consumes 4 bytes and returns -1.2 = #bf99999a
g_ffmt(0) gives 4 bytes: "-1.2"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf99999a = -1.2
fI[1] = #bf999999 = -1.1999999
fI[0] == strtof
Input: 1.3
strtof consumes 3 bytes and returns 1.3 = #3fa66666
g_ffmt(0) gives 3 bytes: "1.3"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fa66666 = 1.3
fI[1] = #3fa66667 = 1.3000001
fI[0] == strtof
Input: -1.3
strtof consumes 4 bytes and returns -1.3 = #bfa66666
g_ffmt(0) gives 4 bytes: "-1.3"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfa66667 = -1.3000001
fI[1] = #bfa66666 = -1.3
fI[1] == strtof
Input: 1.4
strtof consumes 3 bytes and returns 1.4 = #3fb33333
g_ffmt(0) gives 3 bytes: "1.4"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fb33333 = 1.4
fI[1] = #3fb33334 = 1.4000001
fI[0] == strtof
Input: -1.4
strtof consumes 4 bytes and returns -1.4 = #bfb33333
g_ffmt(0) gives 4 bytes: "-1.4"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfb33334 = -1.4000001
fI[1] = #bfb33333 = -1.4
fI[1] == strtof
Input: 1.5
strtof consumes 3 bytes and returns 1.5 = #3fc00000
g_ffmt(0) gives 3 bytes: "1.5"
strtoIf returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtof
Input: -1.5
strtof consumes 4 bytes and returns -1.5 = #bfc00000
g_ffmt(0) gives 4 bytes: "-1.5"
strtoIf returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtof
Input: 1.6
strtof consumes 3 bytes and returns 1.6 = #3fcccccd
g_ffmt(0) gives 3 bytes: "1.6"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fcccccc = 1.5999999
fI[1] = #3fcccccd = 1.6
fI[1] == strtof
Input: -1.6
strtof consumes 4 bytes and returns -1.6 = #bfcccccd
g_ffmt(0) gives 4 bytes: "-1.6"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfcccccd = -1.6
fI[1] = #bfcccccc = -1.5999999
fI[0] == strtof
Input: 1.7
strtof consumes 3 bytes and returns 1.7 = #3fd9999a
g_ffmt(0) gives 3 bytes: "1.7"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fd99999 = 1.6999999
fI[1] = #3fd9999a = 1.7
fI[1] == strtof
Input: -1.7
strtof consumes 4 bytes and returns -1.7 = #bfd9999a
g_ffmt(0) gives 4 bytes: "-1.7"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfd9999a = -1.7
fI[1] = #bfd99999 = -1.6999999
fI[0] == strtof
Input: 1.8
strtof consumes 3 bytes and returns 1.8 = #3fe66666
g_ffmt(0) gives 3 bytes: "1.8"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fe66666 = 1.8
fI[1] = #3fe66667 = 1.8000001
fI[0] == strtof
Input: -1.8
strtof consumes 4 bytes and returns -1.8 = #bfe66666
g_ffmt(0) gives 4 bytes: "-1.8"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfe66667 = -1.8000001
fI[1] = #bfe66666 = -1.8
fI[1] == strtof
Input: 1.9
strtof consumes 3 bytes and returns 1.9 = #3ff33333
g_ffmt(0) gives 3 bytes: "1.9"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3ff33333 = 1.9
fI[1] = #3ff33334 = 1.9000001
fI[0] == strtof
Input: -1.9
strtof consumes 4 bytes and returns -1.9 = #bff33333
g_ffmt(0) gives 4 bytes: "-1.9"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bff33334 = -1.9000001
fI[1] = #bff33333 = -1.9
fI[1] == strtof
Rounding mode for strtor... changed from 1 (nearest) to 2 (toward +Infinity)
Input: 1.1
strtof consumes 3 bytes and returns 1.1 = #3f8ccccd
g_ffmt(0) gives 3 bytes: "1.1"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f8ccccc = 1.0999999
fI[1] = #3f8ccccd = 1.1
fI[1] == strtof
Input: -1.1
strtof consumes 4 bytes and returns -1.0999999 = #bf8ccccc
g_ffmt(0) gives 10 bytes: "-1.0999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf8ccccd = -1.1
fI[1] = #bf8ccccc = -1.0999999
fI[1] == strtof
Input: 1.2
strtof consumes 3 bytes and returns 1.2 = #3f99999a
g_ffmt(0) gives 3 bytes: "1.2"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f999999 = 1.1999999
fI[1] = #3f99999a = 1.2
fI[1] == strtof
Input: -1.2
strtof consumes 4 bytes and returns -1.1999999 = #bf999999
g_ffmt(0) gives 10 bytes: "-1.1999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf99999a = -1.2
fI[1] = #bf999999 = -1.1999999
fI[1] == strtof
Input: 1.3
strtof consumes 3 bytes and returns 1.3000001 = #3fa66667
g_ffmt(0) gives 9 bytes: "1.3000001"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fa66666 = 1.3
fI[1] = #3fa66667 = 1.3000001
fI[1] == strtof
Input: -1.3
strtof consumes 4 bytes and returns -1.3 = #bfa66666
g_ffmt(0) gives 4 bytes: "-1.3"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfa66667 = -1.3000001
fI[1] = #bfa66666 = -1.3
fI[1] == strtof
Input: 1.4
strtof consumes 3 bytes and returns 1.4000001 = #3fb33334
g_ffmt(0) gives 9 bytes: "1.4000001"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fb33333 = 1.4
fI[1] = #3fb33334 = 1.4000001
fI[1] == strtof
Input: -1.4
strtof consumes 4 bytes and returns -1.4 = #bfb33333
g_ffmt(0) gives 4 bytes: "-1.4"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfb33334 = -1.4000001
fI[1] = #bfb33333 = -1.4
fI[1] == strtof
Input: 1.5
strtof consumes 3 bytes and returns 1.5 = #3fc00000
g_ffmt(0) gives 3 bytes: "1.5"
strtoIf returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtof
Input: -1.5
strtof consumes 4 bytes and returns -1.5 = #bfc00000
g_ffmt(0) gives 4 bytes: "-1.5"
strtoIf returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtof
Input: 1.6
strtof consumes 3 bytes and returns 1.6 = #3fcccccd
g_ffmt(0) gives 3 bytes: "1.6"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fcccccc = 1.5999999
fI[1] = #3fcccccd = 1.6
fI[1] == strtof
Input: -1.6
strtof consumes 4 bytes and returns -1.5999999 = #bfcccccc
g_ffmt(0) gives 10 bytes: "-1.5999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfcccccd = -1.6
fI[1] = #bfcccccc = -1.5999999
fI[1] == strtof
Input: 1.7
strtof consumes 3 bytes and returns 1.7 = #3fd9999a
g_ffmt(0) gives 3 bytes: "1.7"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fd99999 = 1.6999999
fI[1] = #3fd9999a = 1.7
fI[1] == strtof
Input: -1.7
strtof consumes 4 bytes and returns -1.6999999 = #bfd99999
g_ffmt(0) gives 10 bytes: "-1.6999999"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfd9999a = -1.7
fI[1] = #bfd99999 = -1.6999999
fI[1] == strtof
Input: 1.8
strtof consumes 3 bytes and returns 1.8000001 = #3fe66667
g_ffmt(0) gives 9 bytes: "1.8000001"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fe66666 = 1.8
fI[1] = #3fe66667 = 1.8000001
fI[1] == strtof
Input: -1.8
strtof consumes 4 bytes and returns -1.8 = #bfe66666
g_ffmt(0) gives 4 bytes: "-1.8"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfe66667 = -1.8000001
fI[1] = #bfe66666 = -1.8
fI[1] == strtof
Input: 1.9
strtof consumes 3 bytes and returns 1.9000001 = #3ff33334
g_ffmt(0) gives 9 bytes: "1.9000001"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3ff33333 = 1.9
fI[1] = #3ff33334 = 1.9000001
fI[1] == strtof
Input: -1.9
strtof consumes 4 bytes and returns -1.9 = #bff33333
g_ffmt(0) gives 4 bytes: "-1.9"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bff33334 = -1.9000001
fI[1] = #bff33333 = -1.9
fI[1] == strtof
Rounding mode for strtor... changed from 2 (toward +Infinity) to 3 (toward -Infinity)
Input: 1.1
strtof consumes 3 bytes and returns 1.0999999 = #3f8ccccc
g_ffmt(0) gives 9 bytes: "1.0999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f8ccccc = 1.0999999
fI[1] = #3f8ccccd = 1.1
fI[0] == strtof
Input: -1.1
strtof consumes 4 bytes and returns -1.1 = #bf8ccccd
g_ffmt(0) gives 4 bytes: "-1.1"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf8ccccd = -1.1
fI[1] = #bf8ccccc = -1.0999999
fI[0] == strtof
Input: 1.2
strtof consumes 3 bytes and returns 1.1999999 = #3f999999
g_ffmt(0) gives 9 bytes: "1.1999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3f999999 = 1.1999999
fI[1] = #3f99999a = 1.2
fI[0] == strtof
Input: -1.2
strtof consumes 4 bytes and returns -1.2 = #bf99999a
g_ffmt(0) gives 4 bytes: "-1.2"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bf99999a = -1.2
fI[1] = #bf999999 = -1.1999999
fI[0] == strtof
Input: 1.3
strtof consumes 3 bytes and returns 1.3 = #3fa66666
g_ffmt(0) gives 3 bytes: "1.3"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fa66666 = 1.3
fI[1] = #3fa66667 = 1.3000001
fI[0] == strtof
Input: -1.3
strtof consumes 4 bytes and returns -1.3000001 = #bfa66667
g_ffmt(0) gives 10 bytes: "-1.3000001"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfa66667 = -1.3000001
fI[1] = #bfa66666 = -1.3
fI[0] == strtof
Input: 1.4
strtof consumes 3 bytes and returns 1.4 = #3fb33333
g_ffmt(0) gives 3 bytes: "1.4"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fb33333 = 1.4
fI[1] = #3fb33334 = 1.4000001
fI[0] == strtof
Input: -1.4
strtof consumes 4 bytes and returns -1.4000001 = #bfb33334
g_ffmt(0) gives 10 bytes: "-1.4000001"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfb33334 = -1.4000001
fI[1] = #bfb33333 = -1.4
fI[0] == strtof
Input: 1.5
strtof consumes 3 bytes and returns 1.5 = #3fc00000
g_ffmt(0) gives 3 bytes: "1.5"
strtoIf returns 1, consuming 3 bytes.
fI[0] == fI[1] == strtof
Input: -1.5
strtof consumes 4 bytes and returns -1.5 = #bfc00000
g_ffmt(0) gives 4 bytes: "-1.5"
strtoIf returns 9, consuming 4 bytes.
fI[0] == fI[1] == strtof
Input: 1.6
strtof consumes 3 bytes and returns 1.5999999 = #3fcccccc
g_ffmt(0) gives 9 bytes: "1.5999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fcccccc = 1.5999999
fI[1] = #3fcccccd = 1.6
fI[0] == strtof
Input: -1.6
strtof consumes 4 bytes and returns -1.6 = #bfcccccd
g_ffmt(0) gives 4 bytes: "-1.6"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfcccccd = -1.6
fI[1] = #bfcccccc = -1.5999999
fI[0] == strtof
Input: 1.7
strtof consumes 3 bytes and returns 1.6999999 = #3fd99999
g_ffmt(0) gives 9 bytes: "1.6999999"
strtoIf returns 33, consuming 3 bytes.
fI[0] = #3fd99999 = 1.6999999
fI[1] = #3fd9999a = 1.7
fI[0] == strtof
Input: -1.7
strtof consumes 4 bytes and returns -1.7 = #bfd9999a
g_ffmt(0) gives 4 bytes: "-1.7"
strtoIf returns 41, consuming 4 bytes.
fI[0] = #bfd9999a = -1.7
fI[1] = #bfd99999 = -1.6999999
fI[0] == strtof
Input: 1.8
strtof consumes 3 bytes and returns 1.8 = #3fe66666
g_ffmt(0) gives 3 bytes: "1.8"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3fe66666 = 1.8
fI[1] = #3fe66667 = 1.8000001
fI[0] == strtof
Input: -1.8
strtof consumes 4 bytes and returns -1.8000001 = #bfe66667
g_ffmt(0) gives 10 bytes: "-1.8000001"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bfe66667 = -1.8000001
fI[1] = #bfe66666 = -1.8
fI[0] == strtof
Input: 1.9
strtof consumes 3 bytes and returns 1.9 = #3ff33333
g_ffmt(0) gives 3 bytes: "1.9"
strtoIf returns 17, consuming 3 bytes.
fI[0] = #3ff33333 = 1.9
fI[1] = #3ff33334 = 1.9000001
fI[0] == strtof
Input: -1.9
strtof consumes 4 bytes and returns -1.9000001 = #bff33334
g_ffmt(0) gives 10 bytes: "-1.9000001"
strtoIf returns 25, consuming 4 bytes.
fI[0] = #bff33334 = -1.9000001
fI[1] = #bff33333 = -1.9
fI[0] == strtof

146
contrib/gdtoa/test/ftest.c Normal file
View File

@ -0,0 +1,146 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_ffmt, strtof, strtoIf, strtopf, and strtorf.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex is a string of <= 8 Hex digits for the internal representation
* of the number, and ndig is a parameters to g_ffmt.
*/
#include "gdtoa.h"
#include <stdio.h>
#include <stdlib.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[1024];
#define U (unsigned long)
int
main(Void)
{
ULong *L;
char *s, *se, *se1;
int dItry, i, i1, ndig = 0, r = 1;
float f, f1, fI[2];
L = (ULong*)&f;
while( (s = fgets(ibuf, sizeof(ibuf), stdin)) !=0) {
while(*s <= ' ')
if (!*s++)
continue;
dItry = 0;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
sscanf(s+1, "%lx", &L[0]);
printf("\nInput: %s", ibuf);
printf(" --> f = #%lx\n", L[0]);
goto fmt_test;
}
dItry = 1;
printf("\nInput: %s", ibuf);
i = strtorf(ibuf, &se, r, &f);
if (r == 1) {
if (f != (i1 = strtopf(ibuf, &se1, &f1), f1)
|| se != se1 || i != i1) {
printf("***strtopf and strtorf disagree!!\n");
if (f != f1)
printf("\tf1 = %g\n", (double)f1);
if (i != i1)
printf("\ti = %d but i1 = %d\n", i, i1);
if (se != se1)
printf("se - se1 = %d\n", (int)(se-se1));
}
if (f != strtof(ibuf, &se1) || se != se1)
printf("***strtof and strtorf disagree!\n");
}
printf("strtof consumes %d bytes and returns %.8g = #%lx\n",
(int)(se-ibuf), f, U *(ULong*)&f);
fmt_test:
se = g_ffmt(obuf, &f, ndig, sizeof(obuf));
printf("g_ffmt(%d) gives %d bytes: \"%s\"\n\n",
ndig, (int)(se-obuf), se ? obuf : "<null>");
if (!dItry)
continue;
printf("strtoIf returns %d,", strtoIf(ibuf, &se, fI, &fI[1]));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (fI[0] == fI[1]) {
if (fI[0] == f)
printf("fI[0] == fI[1] == strtof\n");
else
printf("fI[0] == fI[1] = #%lx = %.8g\n",
U *(ULong*)fI, fI[0]);
}
else {
printf("fI[0] = #%lx = %.8g\nfI[1] = #%lx = %.8g\n",
U *(ULong*)fI, fI[0],
U *(ULong*)&fI[1], fI[1]);
if (fI[0] == f)
printf("fI[0] == strtof\n");
else if (fI[1] == f)
printf("fI[1] == strtof\n");
else
printf("**** Both differ from strtof ****\n");
}
printf("\n");
}
return 0;
}

View File

@ -0,0 +1,68 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include <stdio.h>
#include <stdlib.h>
static char *dir[4] = { "toward zero", "nearest", "toward +Infinity",
"toward -Infinity" };
int
#ifdef KR_headers
getround(r, s) int r; char *s;
#else
getround(int r, char *s)
#endif
{
int i;
i = atoi(s+1);
if (i >= 0 && i < 4) {
printf("Rounding mode for strtor... ");
if (i == r)
printf("was and is %d (%s)\n", i, dir[i]);
else
printf("changed from %d (%s) to %d (%s)\n",
r, dir[r], i, dir[i]);
return i;
}
printf("Bad rounding direction %d: choose among\n", i);
for(i = 0; i < 4; i++)
printf("\t%d (%s)\n", i, dir[i]);
printf("Leaving rounding mode for strtor... at %d (%s)\n", r, dir[r]);
return r;
}

135
contrib/gdtoa/test/makefile Normal file
View File

@ -0,0 +1,135 @@
# /****************************************************************
# Copyright (C) 1998, 2000 by Lucent Technologies
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby
# granted, provided that the above copyright notice appear in all
# copies and that both that the copyright notice and this
# permission notice and warranty disclaimer appear in supporting
# documentation, and that the name of Lucent or any of its entities
# not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
# IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
# THIS SOFTWARE.
#
# ****************************************************************/
.SUFFIXES: .c .o
CC = cc
CFLAGS = -g -I..
A = ../gdtoa.a
.c.o:
$(CC) -c $(CFLAGS) $*.c
all: dt dItest ddtest dtest ftest Qtest xLtest xtest ddtestsi dItestsi tests
dt = dt.o $A
dt: $(dt)
$(CC) -o dt $(dt)
dItest = dItest.o getround.o $A
dItest: $(dItest)
$(CC) -o dItest $(dItest)
ddtest = ddtest.o getround.o $A
ddtest: $(ddtest)
$(CC) -o ddtest $(ddtest)
dtest = dtest.o getround.o $A
dtest: $(dtest)
$(CC) -o dtest $(dtest)
ftest = ftest.o getround.o $A
ftest: $(ftest)
$(CC) -o ftest $(ftest)
Qtest = Qtest.o getround.o $A
Qtest: $(Qtest)
$(CC) -o Qtest $(Qtest)
xtest = xtest.o getround.o $A
xtest: $(xtest)
$(CC) -o xtest $(xtest)
xLtest = xLtest.o getround.o $A
xLtest: $(xLtest)
$(CC) -o xLtest $(xLtest)
strtopddSI.o: strtopddSI.c ../strtopdd.c
strtorddSI.o: strtorddSI.c ../strtordd.c
strtodISI.o: strtodISI.c ../strtodI.c
strtoIddSI.o: strtoIddSI.c ../strtoIdd.c
strtoIdSI.o: strtoIdSI.c ../strtoId.c
ddtestsi = ddtest.o strtopddSI.o strtorddSI.o strtoIddSI.o getround.o $A
ddtestsi: $(ddtestsi)
$(CC) -o ddtestsi $(ddtestsi)
dItestsi = dItest.o strtodISI.o strtoIdSI.o getround.o $A
dItestsi: $(dItestsi)
$(CC) -o dItestsi $(dItestsi)
strtodt = strtodt.o $A
strtodt: $(strtodt)
$(CC) -o strtodt $(strtodt)
# xQtest generates cp commands that depend on sizeof(long double).
# See the source for details. If you know better, create Q.out,
# x.out and xL.out by copying the relevant *.ou0 or *.ou1 files
# to the corresponding .out files. In short, the *.ou0 files are
# for long double == double; x.ou1 and xL.ou1 are for
# long double == extended (a la 80x87 and MC680x0), and Q.ou1 is
# for long double == quad.
Q.out x.out xL.out:
$(CC) -o xQtest xQtest.c
./xQtest | sh
rm -f xQtest xQtest.o
## The rmdir below will fail if any test results differ.
tests: Q.out x.out xL.out dt dItest ddtest dtest ftest Qtest xLtest xtest ddtestsi dItestsi strtodt
mkdir bad
cat testnos testnos1 | ./dt >zap 2>&1
cmp dtst.out zap || mv zap bad/dtst.out
./dItest <testnos >zap 2>&1
cmp dI.out zap || mv zap bad/dI.out
./dItestsi <testnos >zap 2>&1
cmp dIsi.out zap || mv zap bad/dIsi.out
./ddtestsi <testnos >zap 2>&1
cmp ddsi.out zap || mv zap bad/ddsi.out
for i in dd d f x xL Q; do cat testnos rtestnos | \
./"$$i"test >zap 2>&1;\
cmp $$i.out zap || mv zap bad/$$i.out; done
./strtodt testnos3 >bad/strtodt.out && rm bad/strtodt.out || \
cat bad/strtodt.out
rmdir bad
touch tests
xs0 = README Qtest.c dItest.c ddtest.c dtest.c dt.c ftest.c getround.c \
strtoIdSI.c strtoIddSI.c strtodISI.c strtodt.c strtopddSI.c \
strtorddSI.c xLtest.c xQtest.c xtest.c rtestnos testnos testnos1 \
testnos3 dI.out dIsi.out ddsi.out dd.out dtst.out d.out f.out \
x.ou0 xL.ou0 x.ou1 xL.ou1 Q.ou0 Q.ou1 makefile
xsum.out: xsum0.out $(xs0)
xsum $(xs0) >xsum1.out
cmp xsum0.out xsum1.out && mv xsum1.out xsum.out || diff xsum[01].out
clean:
rm -f *.[ao] dt *test *testsi strtodt xsum.out xsum1.out tests zap x.out xL.out Q.out
rm -rf bad

View File

@ -0,0 +1,76 @@
r0
1.1
-1.1
1.2
-1.2
1.3
-1.3
1.4
-1.4
1.5
-1.5
1.6
-1.6
1.7
-1.7
1.8
-1.8
1.9
-1.9
r1
1.1
-1.1
1.2
-1.2
1.3
-1.3
1.4
-1.4
1.5
-1.5
1.6
-1.6
1.7
-1.7
1.8
-1.8
1.9
-1.9
r2
1.1
-1.1
1.2
-1.2
1.3
-1.3
1.4
-1.4
1.5
-1.5
1.6
-1.6
1.7
-1.7
1.8
-1.8
1.9
-1.9
r3
1.1
-1.1
1.2
-1.2
1.3
-1.3
1.4
-1.4
1.5
-1.5
1.6
-1.6
1.7
-1.7
1.8
-1.8
1.9
-1.9

View File

@ -0,0 +1,2 @@
#define Sudden_Underflow
#include "../strtoId.c"

View File

@ -0,0 +1,2 @@
#define Sudden_Underflow
#include "../strtoIdd.c"

View File

@ -0,0 +1,2 @@
#define Sudden_Underflow
#include "../strtodI.c"

View File

@ -0,0 +1,140 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test strtod. */
/* On stdin, read triples: d x y:
* d = decimal string
* x = high-order Hex value expected from strtod
* y = low-order Hex value
* Complain about errors.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int W0, W1;
typedef union {
double d;
long L[2];
} U;
static int
process(char *fname, FILE *f)
{
U a, b;
char buf[2048];
double d;
char *s;
int line, n;
line = n = 0;
top:
while(fgets(s = buf, sizeof(buf), f)) {
line++;
while(*s <= ' ')
if (!*s++)
goto top; /* break 2 */
if (*s == '#')
continue;
while(*s > ' ')
s++;
if (sscanf(s,"\t%lx\t%lx", &a.L[0], &a.L[1]) != 2) {
printf("Badly formatted line %d of %s\n",
line, fname);
n++;
continue;
}
b.d = strtod(buf,0);
if (b.L[W0] != a.L[0] || b.L[W1] != a.L[1]) {
n++;
printf("Line %d of %s: got %lx %lx; expected %lx %lx\n",
line, fname, b.L[W0], b.L[W1], a.L[0], a.L[1]);
}
}
return n;
}
int
main(int argc, char **argv)
{
FILE *f;
char *prog, *s;
int n, rc;
U u;
prog = argv[0];
if (argc == 2 && !strcmp(argv[1],"-?")) {
fprintf(stderr, "Usage: %s [file [file...]]\n"
"\tto read data file(s) of tab-separated triples d x y with\n"
"\t\td decimal string\n"
"\t\tx = high-order Hex value expected from strtod\n"
"\t\ty = low-order Hex value\n"
"\tComplain about errors by strtod.\n"
"\tIf no files, read triples from stdin.\n",
prog);
return 0;
}
/* determine endian-ness */
u.d = 1.;
W0 = u.L[0] == 0;
W1 = 1 - W0;
/* test */
n = rc = 0;
if (argc <= 1)
n = process("<stdin>", stdin);
else
while(s = *++argv)
if (f = fopen(s,"r")) {
n += process(s, f);
fclose(f);
}
else {
rc = 2;
fprintf(stderr, "Cannot open %s\n", s);
}
printf("%d bad conversions\n", n);
if (n)
rc |= 1;
return rc;
}

View File

@ -0,0 +1,2 @@
#define Sudden_Underflow
#include "../strtopdd.c"

View File

@ -0,0 +1,2 @@
#define Sudden_Underflow
#include "../strtordd.c"

View File

@ -0,0 +1,28 @@
1.23
1.23e+20
1.23e-20
1.23456789
1.23456589e+20
1.23e+30
1.23e-30
1.23456789e-20
1.23456789e-30
1.234567890123456789
1.23456789012345678901234567890123456789
1.23e306
1.23e-306
1.23e-320
1.23e-20
1.23456789e307
1.23456589e-307
1.234567890123456789
1.234567890123456789e301
1.234567890123456789e-301
1.234567890123456789e-321
1e23
1e310
9.0259718793241475e-277
9.025971879324147880346310405869e-277
9.025971879324147880346310405868e-277
2.2250738585072014e-308
2.2250738585072013e-308

View File

@ -0,0 +1,20 @@
1.23:2 6
1.23:4 6
1.23e+20:2 6
1.23e+20:4 6
1.23e-20:2 6
1.23e-20:4 6
1.23456789:2 6
1.23456789:4 6
1.23456589e+20:2 6
1.23456589e+20:4 6
1.23456789e-20:2 6
1.23456789e-20:4 6
1234565:2 6
1234565:4 6
1.234565:2 6
1.234565:4 6
1.234565e+20:2 6
1.234565e+20:4 6
1.234565e-20:2 6
1.234565e-20:4 6

328
contrib/gdtoa/test/testnos3 Normal file
View File

@ -0,0 +1,328 @@
# Test triples for strtodt, derived from Fred Tydeman's posting
# of 26 February 1996 to comp.arch.arithmetic.
9e0306 7fa9a202 8368022e
4e-079 2fa7b6d7 1d20b96c
7e-261 9eb8d7e 32be6396
6e-025 3ae7361c b863de62
7e-161 1eaf7e0d b3799aa3
7e0289 7c1cbb54 7777a285
5e0079 507afcef 51f0fb5f
1e0080 508afcef 51f0fb5f
7e-303 1333391 31c46f8b
5e0152 5fa317e5 ef3ab327
5e0125 5a07a2ec c414a03f
2e0126 5a27a2ec c414a03f
7e-141 22d5570f 59bd178c
4e-192 18323ff0 6eea847a
9e0043 49102498 ea6df0c4
1e0303 7ed754e3 1cd072da
95e-089 2dde3cbc 9907fdc8
85e0194 689d1c26 db7d0dae
69e0267 77c0b7cb 60c994da
97e-019 3c665dde 8e688ba6
37e0046 49d033d7 eca0adef
74e0046 49e033d7 eca0adef
61e-099 2bc0ad83 6f269a17
53e-208 151b39ae 1909c31b
93e-234 fc27b2e 4f210075
79e-095 2c9a5db8 12948281
87e-274 772d36c f48e7abd
83e0025 4585747a b143e353
17e-036 38b698cc dc60015a
53e0033 47246a34 18629ef6
51e-074 30ecd5be e57763e6
63e-022 3bbdc03b 8fd7016a
839e0143 5e3ae03f 245703e2
749e-182 1abf1472 7744c63e
999e-026 3b282782 afe1869e
345e0266 77b0b7cb 60c994da
914e-102 2b5ffc81 bc29f02b
829e0102 55b7221a 79cdd1d9
307e0090 5322d6b1 83fe4b55
859e0182 6654374d 8b87ac63
283e0085 5216c309 24bab4b
589e0187 675526be 9c22eb17
302e0176 64fdcf7d f8f573b7
604e0176 650dcf7d f8f573b7
761e-244 de03cea 3586452e
647e0230 7044d64d 4079150c
755e0174 64a7d931 93f78fc6
255e-075 30dcd5be e57763e6
3391e0055 4c159bd3 ad46e346
4147e-015 3d923d1b 5eb1d778
3996e-026 3b482782 afe1869e
1998e-026 3b382782 afe1869e
3338e-296 335519a c5142aab
1669e-296 325519a c5142aab
8699e-276 772d2df 246ecd2d
5311e0243 73284e91 f4aa0fdb
7903e-096 2cd07c2d 27a5b989
7611e-226 11d19b87 44033457
3257e0058 4cb444b3 4a6fb3eb
6514e0058 4cc444b3 4a6fb3eb
3571e0263 77462644 c61d41aa
7142e0263 77562644 c61d41aa
5311e0242 72f3720e 5d54d97c
1617e-063 3384c98f ce16152e
51881e0037 4897d295 dc76da4
31441e-118 285ef890 f5de4c86
30179e0079 5143e272 a77478e8
60358e0079 5153e272 a77478e8
63876e-020 3cc70385 6844bdbf
31938e-020 3cb70385 6844bdbf
46073e-032 3a42405b 773fbdf3
32941e0051 4b757eb8 ad52a5c9
82081e0041 49770105 df3d47cb
38701e-215 1440492a 4a8a37fd
62745e0047 4ab0c52f e6dc6a1b
12549e0048 4ac0c52f e6dc6a1b
64009e-183 1af099b3 93b84832
89275e0261 77262644 c61d41aa
75859e0025 46232645 e1ba93f0
57533e0287 7c8272ed 2307f56a
584169e0229 70ad6570 59dc79aa
940189e-112 29eb99d6 240c1a28
416121e0197 6a00fd07 ed297f80
832242e0197 6a10fd07 ed297f80
584738e0076 50e8a85e b277e645
933587e-140 241b2487 28b9c117
252601e0121 5a2dda59 2e398dd7
358423e0274 79f9463b 59b8f2bd
892771e-213 14f25818 c7294f27
410405e0040 49670105 df3d47cb
928609e-261 afbe2dd 66200bef
302276e-254 c55a462 d91c6ab3
920657e-023 3c653a99 85dbde6c
609019e-025 3bf1f99e 11ea0a24
252601e0120 59f7e1e0 f1c7a4ac
654839e-060 34b00e7d b3b3f242
8823691e0130 5c5e597c b94b7ae
2920845e0228 709d6570 59dc79aa
9210917e0080 51fda232 347e6032
5800419e-303 26e58ff a48f4fce
6119898e-243 ee3ecf2 2ea07863
3059949e-243 ed3ecf2 2ea07863
2572231e0223 6f90f73b e1dff9ad
5444097e-021 3cf8849d d33c95af
5783893e-127 26f7e590 2ce0e151
3865421e-225 1295d4fe 53afec65
4590831e0156 61b4689b 4a5fa201
9181662e0156 61c4689b 4a5fa201
5906361e-027 3bbbe45a 312d08a0
7315057e0235 7225f0d4 8362a72
9088115e0106 5762e51a 84a3c6a0
1817623e0107 5772e51a 84a3c6a0
44118455e0129 5c4e597c b94b7ae
35282041e0293 7e5512d5 273e62e8
31279898e-291 5129b01 b6885d36
15639949e-291 5029b01 b6885d36
27966061e0145 5f955bcf 72fd10f9
55932122e0145 5fa55bcf 72fd10f9
70176353e-053 36900683 a21de855
40277543e-032 3adf29ca ff893b1
50609263e0157 622193af f1f1c8e3
66094077e0077 518b37c4 b7928317
84863171e0114 59406e98 f5ec8f37
89396333e0264 786526f0 61ca9053
87575437e-309 16e0732 602056c
78693511e-044 3870bc7b 7603a2ca
90285923e-206 16d14700 83f89d48
30155207e-030 3b423a4a d20748a2
245540327e0121 5acc569e 968e0944
263125459e0287 7d44997a 298b2f2e
566446538e-257 c64472b a9550e86
283223269e-257 c54472b a9550e86
245540327e0122 5b01b623 1e18c5cb
491080654e0122 5b11b623 1e18c5cb
971212611e-126 27a397d3 c9745d2f
229058583e0052 4c76ce94 febdc7a5
325270231e0039 49cc7ccf 90c9f8ab
989648089e-035 3a8880a3 d515e849
653777767e0273 7a720223 f2b3a881
923091487e0209 6d30bc60 e6896717
526250918e0288 7d89bfd8 b3edfafa
350301748e-309 18e0732 602056c
741111169e-203 17a14fe7 daf8f3ae
667284113e-240 ff09355 f8050c02
1227701635e0120 5abc569e 968e0944
9981396317e-182 1c38afe1 a2a66aa
5232604057e-298 41465b8 96c24520
5572170023e-088 2fb08478 22f765b2
1964322616e0122 5b31b623 1e18c5cb
3928645232e0122 5b41b623 1e18c5cb
8715380633e-058 35f4614c 3219891f
4856063055e-127 279397d3 c9745d2f
8336960483e-153 223a06a1 24b95e1
1007046393e-155 21a01891 fc4717fd
5378822089e-176 1d695fd4 c88d4b1b
5981342308e-190 1a83db11 ac608107
7214782613e-086 3020b552 d2edcdea
5458466829e0142 5f70acde 6a98eb4c
9078555839e-109 2b5fc575 867314ee
6418488827e0079 526021f1 4ed7b3fa
65325840981e0069 5081a151 ddbd3c4a
49573485983e0089 54a221bd 871d2cf4
46275205733e0074 51830e6c 7d4e3480
92550411466e0074 51930e6c 7d4e3480
41129842097e-202 1832c3e7 2d179607
93227267727e-049 380960fe 8d5847f
41297294357e0185 688c4943 7fccfadb
41534892987e-067 343a1266 6477886d
42333842451e0201 6be0189a 26df575f
78564021519e-227 13115551 5fd37265
53587107423e-061 35800a19 a3ffd981
53827010643e-200 18a32fa6 9a69bd6d
83356057653e0193 6a4544e6 daee2a18
45256834646e-118 29a541ec dfd48694
45392779195e-110 2b4fc575 867314ee
23934638219e0291 7e81deaf 40ead9a0
995779191233e0113 59e2d44e dcc51304
997422852243e-265 b676688 faee99bc
653532977297e-123 28d925a0 aabcdc68
938885684947e0147 60f11894 b202e9f4
619534293513e0124 5c210c20 303fe0f1
539879452414e-042 39a5e66d c3d6bdb5
742522891517e0259 782c1c35 2fc3c309
254901016865e-022 3dbc06d3 66394441
685763015669e0280 7c85fd7a a44d9477
384865004907e-285 72aa65b 58639e69
286556458711e0081 5321958b 36c5102b
573112917422e0081 5331958b 36c5102b
769525178383e-150 234253ec e161420
416780288265e0192 6a3544e6 daee2a18
226963895975e-111 2b3fc575 867314ee
665592809339e0063 4f778b65 16c2b478
3891901811465e0217 6f99ab82 61990292
4764593340755e0069 50e4177a 9915fbf8
6336156586177e0269 7a7173f7 6c63b792
8233559360849e0095 56566fee 5649a7a
3662265515198e-107 2c538e6e dd48f2a3
1831132757599e-107 2c438e6e dd48f2a3
7812878489261e-179 1d726dae 7bbeda75
6363857920591e0145 60b28a61 cf9483b7
8811915538555e0082 53a51f50 8b287ae7
9997878507563e-195 1a253db2 fea1ea31
9224786422069e-291 634ee5d 56b32957
6284426329974e-294 58d3409 dfbca26f
9199302046091e-062 35c13597 2630774c
6070482281213e-122 29423fa9 e6fcf47e
2780161250963e-301 405acc2 53064c2
8233559360849e0094 5621f324 d11d4862
72027097041701e0206 6d946778 12d3a606
97297545286625e0215 6f79ab82 61990292
99021992302453e-025 3da5c671 4def374c
54104687080198e-022 3e373cdf 8db7a7bc
33519685743233e0089 5537f203 339c9629
67039371486466e0089 5547f203 339c9629
39064392446305e-180 1d626dae 7bbeda75
17796979903653e0261 78e072f3 819c1321
28921916763211e0038 4a9eebab e0957af3
87605699161665e0155 6302920f 96e7f9ef
41921560615349e-067 34d9b2a5 c4041e4b
80527976643809e0061 4f7c7c5a ea080a49
72335858886654e-159 21cce77c 2b3328fc
52656615219377e0102 57f561de f4a9ee32
15400733123779e-072 33b8bf7e 7fa6f02a
77003665618895e-073 33a8bf7e 7fa6f02a
475603213226859e-042 3a42d730 88f4050a
972708181182949e0116 5b218a7f 36172332
246411729980464e-071 342eef5e 1f90ac34
123205864990232e-071 341eef5e 1f90ac34
609610927149051e-255 e104273 b18918b1
475603213226859e-041 3a778cfc ab31064d
672574798934795e0065 508226c6 84c87261
134514959786959e0066 509226c6 84c87261
294897574603217e-151 2395f2df 5e675a0f
723047919080275e0036 4a7eebab e0957af3
660191429952702e-088 30bddc7e 975c5045
330095714976351e-088 30addc7e 975c5045
578686871093232e-159 21fce77c 2b3328fc
144671717773308e-159 21dce77c 2b3328fc
385018328094475e-074 3398bf7e 7fa6f02a
330095714976351e-089 3077e398 7916a69e
2215901545757777e-212 171a80a6 e566428c
1702061899637397e-276 9cacc46 749dccfe
1864950924021923e0213 6f53ae60 753af6ca
3729901848043846e0213 6f63ae60 753af6ca
7487252720986826e-165 20f8823a 57adbef9
3743626360493413e-165 20e8823a 57adbef9
4988915232824583e0119 5be5f6de 9d5d6b5b
3771476185376383e0277 7cae3c14 d6916ce9
6182410494241627e-119 2a81b964 58445d07
2572981889477453e0142 609dfc11 fbf46087
7793560217139653e0051 4dd28046 1b856ec5
9163942927285259e-202 194fe601 457dce4d
6353227084707473e0155 63650aff 653ffe8a
4431803091515554e-211 17609068 4f5fe998
9324754620109615e0211 6f0f7d67 21f7f144
8870461176410409e0263 79d90529 a37b7e22
90372559027740405e0143 612491da ad0ba280
18074511805548081e0146 61a011f2 d73116f4
54897030182071313e0029 496ec556 66d8f9ec
76232626624829156e-032 3ccb7738 11e75fe
59898021767894608e-165 2128823a 57adbef9
29949010883947304e-165 2118823a 57adbef9
26153245263757307e0049 4d83de00 5bd620df
27176258005319167e-261 d27c074 7bd76fa1
18074511805548081e0147 61d4166f 8cfd5cb1
24691002732654881e-115 2b759a27 83ce70ab
58483921078398283e0057 4f408ce4 99519ce3
64409240769861689e-159 22692238 f7987779
94080055902682397e-242 11364981 e39e66ca
31766135423537365e0154 63550aff 653ffe8a
68985865317742005e0164 657a999d dec72aca
13797173063548401e0165 658a999d dec72aca
902042358290366539e-281 9522dc0 1ca1cb8c
238296178309629163e0272 7c038fd9 3f1f5342
783308178698887621e0226 72925ae6 2cb346d8
439176241456570504e0029 499ec556 66d8f9ec
899810892172646163e0283 7e6adf51 fa055e03
926145344610700019e-225 14f307a6 7f1f69ff
653831131593932675e0047 4d63de00 5bd620df
130766226318786535e0048 4d73de00 5bd620df
557035730189854663e-294 693bfac 6bc4767b
902042358290366539e-280 986b930 23ca3e6f
272104041512242479e0200 6d13bbb4 bf05f087
544208083024484958e0200 6d23bbb4 bf05f087
680429695511221511e0192 6b808ebc 116f8a20
308975121073410857e0236 7490db75 cc001072
792644927852378159e0078 53d7bff3 36d8ff06
783308178698887621e0223 71f2cbac 35f71140
8396094300569779681e-252 f8ab223 efcee35a
3507665085003296281e-074 346b85c0 26a264e4
7322325862592278999e0074 5336775b 6caa5ae0
6014546754280072926e0209 6f396397 b06732a4
7120190517612959703e0120 5cc3220d cd5899fd
3507665085003296281e-073 34a13398 18257f0f
4345544743100783551e-218 168a9c42 e5b6d89f
9778613303868468131e-090 313146fe 1075e1ef
7539204280836061195e-082 32d3d969 e3dbe723
7862637540082247119e-202 19eaba32 62ee707b
2176832332097939832e0200 6d43bbb4 bf05f087
8643988913946659879e0115 5bbe71ec 1ed0a4f9
5529436763613147623e0138 6079c677 be6f236e
6764958008109694533e-173 1fed0669 2e6f5ef6
6802601037806061975e0197 6cbf92ba cb3cb40c
1360520207561212395e0198 6ccf92ba cb3cb40c
62259110684423957791e0047 4dcd8f2c fc20d6e8
88800290202542652011e-226 1526cec5 1a43f41a
41010852717673354694e-221 16201295 4b6aabba
20505426358836677347e-221 16101295 4b6aabba
66102447903809911604e0055 4f776206 8a24fd55
35600952588064798515e0119 5cb3220d cd5899fd
14371240869903838702e0205 6e78d92d 2bcc7a81
57500690832492901689e0043 4cf65d3e 2acd616b
23432630639573022093e-107 2dbdd54c 40a2f25f
62259110684423957791e0048 4e02797c 1d948651
35620497849450218807e-306 475b220 82529425
69658634627134074624e0200 6d93bbb4 bf05f087
99440755792436956989e-062 37362d10 462a26f4
55277197169490210673e0081 54d945bf a911e32a
36992084760177624177e-318 1f8c5f9 551c2f9a
30888265282878466443e-111 2cf01b8e f28251fc
# examples of bugs introduced 20001113, fixed 20010207
# first is 2^-1075 (half the smallest denormal)
2.4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125e-324 0 0
2.47032822920623272e-324 0 0

1182
contrib/gdtoa/test/x.ou0 Normal file

File diff suppressed because it is too large Load Diff

1460
contrib/gdtoa/test/x.ou1 Normal file

File diff suppressed because it is too large Load Diff

1182
contrib/gdtoa/test/xL.ou0 Normal file

File diff suppressed because it is too large Load Diff

1183
contrib/gdtoa/test/xL.ou1 Normal file

File diff suppressed because it is too large Load Diff

169
contrib/gdtoa/test/xLtest.c Normal file
View File

@ -0,0 +1,169 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_xLfmt, strtoIxL, strtopxL, and strtorxL.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex0 hex1 hex2
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex0 is a string of <= 8 Hex digits for the most significant
* word of the number, hex1 is a similar string for the next
* word, etc., and ndig is a parameters to g_xLfmt.
*/
#include "gdtoa.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[2048];
#define U (unsigned long)
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#endif
#ifdef IEEE_8087
#define _0 2
#define _1 1
#define _2 0
#endif
int
main(Void)
{
char *s, *se, *se1;
int dItry, i, ndig = 0, r = 1;
union { long double d; ULong bits[3]; } u, v[2];
while(s = fgets(ibuf, sizeof(ibuf), stdin)) {
while(*s <= ' ')
if (!*s++)
continue;
dItry = 0;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
sscanf(s+1, "%lx %lx %lx", &u.bits[_0],
&u.bits[_1], &u.bits[_2]);
printf("\nInput: %s", ibuf);
printf(" --> f = #%lx %lx %lx\n", u.bits[_0],
u.bits[_1], u.bits[_2]);
goto fmt_test;
}
dItry = 1;
printf("\nInput: %s", ibuf);
i = strtorxL(ibuf, &se, r, u.bits);
if (r == 1 && (i != strtopxL(ibuf, &se1, v[0].bits) || se1 != se
|| memcmp(u.bits, v[0].bits, 12)))
printf("***strtoxL and strtorxL disagree!!\n:");
printf("\nstrtoxL consumes %d bytes and returns %d\n",
(int)(se-ibuf), i);
printf("with bits = #%lx %lx %lx\n",
U u.bits[_0], U u.bits[_1], U u.bits[_2]);
if (sizeof(long double) == 12)
printf("printf(\"%%.21Lg\") gives %.21Lg\n", u.d);
fmt_test:
se = g_xLfmt(obuf, u.bits, ndig, sizeof(obuf));
printf("g_xLfmt(%d) gives %d bytes: \"%s\"\n\n",
ndig, (int)(se-obuf), se ? obuf : "<null>");
if (!dItry)
continue;
printf("strtoIxL returns %d,",
strtoIxL(ibuf, &se, v[0].bits, v[1].bits));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (!memcmp(v[0].bits, v[1].bits, 12)) {
if (!memcmp(u.bits, v[0].bits, 12))
printf("fI[0] == fI[1] == strtoxL\n");
else {
printf("fI[0] == fI[1] = #%lx %lx %lx\n",
U v[0].bits[_0], U v[0].bits[_1],
U v[0].bits[_2]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[0].d);
}
}
else {
printf("fI[0] = #%lx %lx %lx\n",
U v[0].bits[_0], U v[0].bits[_1],
U v[0].bits[_2]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[0].d);
printf("fI[1] = #%lx %lx %lx\n",
U v[1].bits[_0], U v[1].bits[_1],
U v[1].bits[_2]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[1].d);
if (!memcmp(v[0].bits, u.bits, 12))
printf("fI[0] == strtoxL\n");
else if (!memcmp(v[1].bits, u.bits, 12))
printf("fI[1] == strtoxL\n");
else
printf("**** Both differ from strtod ****\n");
}
printf("\n");
}
return 0;
}

View File

@ -0,0 +1,46 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 2002 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
#include <stdio.h>
int
main(void)
{
switch(sizeof(long double)) {
case 10:
case 12:
printf("cp x.ou1 x.out; cp xL.ou1 xL.out; cp Q.ou0 Q.out\n");
break;
case 16:
printf("cp x.ou0 x.out; cp xL.ou0 xL.out; cp Q.ou1 Q.out\n");
break;
default:
printf("cp x.ou0 x.out; cp xL.ou0 xL.out; cp Q.ou0 Q.out\n");
}
return 0;
}

View File

@ -0,0 +1,35 @@
README e6ebdc91 2429
Qtest.c 140625e2 4778
dItest.c 8689031 2401
ddtest.c ea24d330 4943
dtest.c 900d971 4071
dt.c addb61c 6198
ftest.c f609ce43 3958
getround.c f471599 2041
strtoIdSI.c 7bfb88b 49
strtoIddSI.c 72e8852 50
strtodISI.c ed08b740 49
strtodt.c 17aca428 3213
strtopddSI.c 13e7138d 50
strtorddSI.c f7e4b1d5 50
xLtest.c faca328f 4646
xQtest.c efdea3a2 1549
xtest.c 1f19b87 4858
rtestnos f94bcdf6 336
testnos e89999d6 485
testnos1 7e16229 294
testnos3 fa5c8aca 11998
dI.out d522eef 4369
dIsi.out 1dd6d02f 4350
ddsi.out 1f94bbe2 10251
dd.out e262456e 40923
dtst.out ee75f6b9 23308
d.out f271efc9 28131
f.out 4b0bd51 21207
x.ou0 1cfc5d22 25378
xL.ou0 faa3a741 26363
x.ou1 1a7e9dd4 34587
xL.ou1 418057a 26476
Q.ou0 e4592b85 28742
Q.ou1 ea0b344d 39572
makefile ebbea1e1 4191

176
contrib/gdtoa/test/xtest.c Normal file
View File

@ -0,0 +1,176 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998-2001 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
/* Test program for g_xfmt, strtoIx, strtopx, and strtorx.
*
* Inputs (on stdin):
* r rounding_mode
* n ndig
* number
* #hex0 hex1 hex2 hex3 hex4
*
* rounding_mode values:
* 0 = toward zero
* 1 = nearest
* 2 = toward +Infinity
* 3 = toward -Infinity
*
* where number is a decimal floating-point number,
* hex0 is a string of <= 4 Hex digits for the most significant
* half-word of the number, hex1 is a similar string for the next
* half-word, etc., and ndig is a parameters to g_xfmt.
*/
#include "gdtoa.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int getround ANSI((int,char*));
static char ibuf[2048], obuf[2048];
#undef _0
#undef _1
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
#define _2 2
#define _3 3
#define _4 4
#endif
#ifdef IEEE_8087
#define _0 4
#define _1 3
#define _2 2
#define _3 1
#define _4 0
#endif
int
main(Void)
{
char *s, *se, *se1;
int i, dItry, ndig = 0, r = 1;
union { long double d; UShort bits[5]; } u, v[2];
while(s = fgets(ibuf, sizeof(ibuf), stdin)) {
while(*s <= ' ')
if (!*s++)
continue;
dItry = 0;
switch(*s) {
case 'r':
r = getround(r, s);
continue;
case 'n':
i = s[1];
if (i <= ' ' || i >= '0' && i <= '9') {
ndig = atoi(s+1);
continue;
}
break; /* nan? */
case '#':
sscanf(s+1, "%hx %hx %hx %hx hx", &u.bits[_0],
&u.bits[_1], &u.bits[_2], &u.bits[_3],
&u.bits[_4]);
printf("\nInput: %s", ibuf);
printf(" --> f = #%x %x %x %x %x\n", u.bits[_0],
u.bits[_1], u.bits[_2], u.bits[_3], u.bits[4]);
goto fmt_test;
}
dItry = 1;
printf("\nInput: %s", ibuf);
i = strtorx(ibuf, &se, r, u.bits);
if (r == 1 && (i != strtopx(ibuf, &se1, v[0].bits) || se1 != se
|| memcmp(u.bits, v[0].bits, 10)))
printf("***strtox and strtorx disagree!!\n:");
printf("\nstrtox consumes %d bytes and returns %d\n",
(int)(se-ibuf), i);
printf("with bits = #%x %x %x %x %x\n",
u.bits[_0], u.bits[_1], u.bits[_2],
u.bits[_3], u.bits[_4]);
if (sizeof(long double) == 12)
printf("printf(\"%%.21Lg\") gives %.21Lg\n", u.d);
fmt_test:
se = g_xfmt(obuf, u.bits, ndig, sizeof(obuf));
printf("g_xfmt(%d) gives %d bytes: \"%s\"\n\n",
ndig, (int)(se-obuf), se ? obuf : "<null>");
if (!dItry)
continue;
printf("strtoIx returns %d,",
strtoIx(ibuf, &se, v[0].bits, v[1].bits));
printf(" consuming %d bytes.\n", (int)(se-ibuf));
if (!memcmp(v[0].bits, v[1].bits, 10)) {
if (!memcmp(u.bits, v[0].bits, 10))
printf("fI[0] == fI[1] == strtox\n");
else {
printf("fI[0] == fI[1] = #%x %x %x %x %x\n",
v[0].bits[_0], v[0].bits[_1],
v[0].bits[_2], v[0].bits[_3],
v[0].bits[_4]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[0].d);
}
}
else {
printf("fI[0] = #%x %x %x %x %x\n",
v[0].bits[_0], v[0].bits[_1],
v[0].bits[_2], v[0].bits[_3],
v[0].bits[_4]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[0].d);
printf("fI[1] = #%x %x %x %x %x\n",
v[1].bits[_0], v[1].bits[_1],
v[1].bits[_2], v[0].bits[_3],
v[0].bits[_4]);
if (sizeof(long double) == 12)
printf("= %.21Lg\n", v[1].d);
if (!memcmp(v[0].bits, u.bits, 10))
printf("fI[0] == strtox\n");
else if (!memcmp(v[1].bits, u.bits, 10))
printf("fI[1] == strtox\n");
else
printf("**** Both differ from strtod ****\n");
}
printf("\n");
}
return 0;
}

76
contrib/gdtoa/ulp.c Normal file
View File

@ -0,0 +1,76 @@
/****************************************************************
The author of this software is David M. Gay.
Copyright (C) 1998, 1999 by Lucent Technologies
All Rights Reserved
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of Lucent or any of its entities
not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
****************************************************************/
/* Please send bug reports to
David M. Gay
Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-0636
U.S.A.
dmg@bell-labs.com
*/
#include "gdtoaimp.h"
double
ulp
#ifdef KR_headers
(x) double x;
#else
(double x)
#endif
{
Long L;
double a;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Sudden_Underflow
if (L > 0) {
#endif
#ifdef IBM
L |= Exp_msk1 >> 4;
#endif
word0(a) = L;
word1(a) = 0;
#ifndef Sudden_Underflow
}
else {
L = -L >> Exp_shift;
if (L < Exp_shift) {
word0(a) = 0x80000 >> L;
word1(a) = 0;
}
else {
word0(a) = 0;
L -= Exp_shift;
word1(a) = L >= 31 ? 1 : 1 << 31 - L;
}
}
#endif
return a;
}

46
contrib/gdtoa/xsum0.out Normal file
View File

@ -0,0 +1,46 @@
README 10a65619 13093
arithchk.c e37b8a75 4070
dmisc.c e8d262b6 4712
dtoa.c f3c132b3 16905
g_Qfmt.c e5847e9 2870
g__fmt.c f2d66617 2355
g_ddfmt.c fcf94527 3790
g_dfmt.c f30e55a9 2533
g_ffmt.c 7c4ea96 2459
g_xLfmt.c 36ee116 2716
g_xfmt.c c20a5e4 2795
gdtoa.c 364a0d2 17017
gdtoa.h 1eb440de 4810
gdtoaimp.h 6a955ba 19106
gethex.c f56c1968 5041
gmisc.c e1a268ea 2114
hd_init.c cf9a94e 1827
hexnan.c f53be1da 2988
makefile e84d078f 2802
misc.c ea539bdb 14168
smisc.c f659f036 3685
strtoIQ.c 13ac9f44 1969
strtoId.c d05a7a6 1961
strtoIdd.c fa36260d 2135
strtoIf.c eb75ac99 1905
strtoIg.c ec59c2fa 3484
strtoIx.c 8f8c9d 1990
strtoIxL.c 1313ff7f 1961
strtod.c 1390a957 20277
strtodI.c e58338e0 4062
strtodg.c 1cba0060 19769
strtof.c 1e7a787a 2202
strtopQ.c e232c542 2685
strtopd.c e865dc64 1701
strtopdd.c 1c240126 4540
strtopf.c 1c762782 2196
strtopx.c 17c3fafb 2665
strtopxL.c ed474cdb 2505
strtorQ.c 126cc92b 2898
strtord.c 1fce44b9 2528
strtordd.c c32bca0 4979
strtorf.c fe6a2687 2430
strtorx.c 18389f0c 2888
strtorxL.c f63fc249 2730
sum.c dc07b9b 2524
ulp.c f6db0b4d 1894