summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2011-03-12 07:03:06 +0000
committerdas <das@FreeBSD.org>2011-03-12 07:03:06 +0000
commit22b42559b254072c025ee7660742d9096d6ddbfd (patch)
tree02fea95a802135fbb5d2f67a8c005bf132b6e256
parentbb4fe3b8f6c28c422e237503dec22ccea5269dba (diff)
parenta0113107f8ebf649eb6c0730ece07fe0865a384b (diff)
downloadFreeBSD-src-22b42559b254072c025ee7660742d9096d6ddbfd.zip
FreeBSD-src-22b42559b254072c025ee7660742d9096d6ddbfd.tar.gz
Merge gdtoa-20110304.
-rw-r--r--contrib/gdtoa/README7
-rw-r--r--contrib/gdtoa/changes672
-rw-r--r--contrib/gdtoa/dtoa.c168
-rw-r--r--contrib/gdtoa/g__fmt.c2
-rw-r--r--contrib/gdtoa/g_ddfmt.c23
-rw-r--r--contrib/gdtoa/g_dfmt.c2
-rw-r--r--contrib/gdtoa/gdtoa.c172
-rw-r--r--contrib/gdtoa/gdtoa.h2
-rw-r--r--contrib/gdtoa/gdtoaimp.h47
-rw-r--r--contrib/gdtoa/gethex.c10
-rw-r--r--contrib/gdtoa/hexnan.c54
-rw-r--r--contrib/gdtoa/makefile41
-rw-r--r--contrib/gdtoa/misc.c64
-rw-r--r--contrib/gdtoa/printf.c8
-rw-r--r--contrib/gdtoa/printf.c01669
-rw-r--r--contrib/gdtoa/smisc.c20
-rw-r--r--contrib/gdtoa/stdio1.h103
-rw-r--r--contrib/gdtoa/strtoIg.c2
-rw-r--r--contrib/gdtoa/strtod.c446
-rw-r--r--contrib/gdtoa/strtodI.c88
-rw-r--r--contrib/gdtoa/strtodg.c121
-rw-r--r--contrib/gdtoa/strtof.c2
-rw-r--r--contrib/gdtoa/strtopdd.c36
-rw-r--r--contrib/gdtoa/strtopf.c2
-rw-r--r--contrib/gdtoa/strtopx.c3
-rw-r--r--contrib/gdtoa/strtopxL.c3
-rw-r--r--contrib/gdtoa/strtordd.c34
-rw-r--r--contrib/gdtoa/strtorf.c2
-rw-r--r--contrib/gdtoa/strtorx.c3
-rw-r--r--contrib/gdtoa/strtorxL.c3
-rw-r--r--contrib/gdtoa/ulp.c20
31 files changed, 3183 insertions, 646 deletions
diff --git a/contrib/gdtoa/README b/contrib/gdtoa/README
index ce8be55..0c034f1 100644
--- a/contrib/gdtoa/README
+++ b/contrib/gdtoa/README
@@ -353,5 +353,12 @@ you also compile with -DNO_LOCALE_CACHE, the details about the
current "decimal point" character string are cached and assumed not
to change during the program's execution.
+On machines with a 64-bit long double and perhaps a 113-bit "quad"
+type, you can invoke "make Printf" to add Printf (and variants, such
+as Fprintf) to gdtoa.a. These are analogs, declared in stdio1.h, of
+printf and fprintf, etc. in which %La, %Le, %Lf, and %Lg are for long
+double and (if appropriate) %Lqa, %Lqe, %Lqf, and %Lqg are for quad
+precision printing.
+
Please send comments to David M. Gay (dmg at acm dot org, with " at "
changed at "@" and " dot " changed to ".").
diff --git a/contrib/gdtoa/changes b/contrib/gdtoa/changes
new file mode 100644
index 0000000..3eb8138
--- /dev/null
+++ b/contrib/gdtoa/changes
@@ -0,0 +1,672 @@
+Sun Jun 30 13:48:26 EDT 1991:
+ dtoa.c: adjust dtoa to allow negative ndigits for modes 3,5,7,9
+(fixed-point mode); fix rounding bug in these modes when the input
+d (to be converted) satisfies 10^-(ndigits+1) <= |d| < 10^-ndigits ,
+i.e., when the result, before rounding, would be empty but might
+round to one digit. Adjust the decpt returned in these modes when
+the result is empty (i.e., when |d| <= 5 * 10^-ndigits).
+
+Tue Jul 2 21:44:00 EDT 1991
+ Correct an inefficiency introduced 2 days ago in dtoa's handling of
+integers in modes 0, 1.
+
+Mon Sep 9 23:29:38 EDT 1991
+ dtoa.c: remove superfluous declaration of size_t.
+
+Sun Oct 6 15:34:15 EDT 1991
+ dtoa.c: fix another bug in modes 3,5,7,9 when the result, before
+rounding, would be empty, but rounds to one digit: *decpt was low by
+one.
+
+Sat Jan 18 12:30:04 EST 1992
+ dtoa.c: add some #ifdef KR_headers lines relevant only if IBM is
+defined; for input decimal strings representing numbers too large, have
+strtod return HUGE_VAL only if __STDC__ is defined; otherwise have it
+return +-Infinity for IEEE arithmetic, +- the largest machine number
+for IBM and VAX arithmetic. (If __STDC__ is not defined, HUGE_VAL may
+not be defined either, or it may be wrong.)
+
+Mon Apr 27 23:13:43 EDT 1992
+ dtoa.c: tweak strtod (one-line addition) so the end-pointer = start
+pointer when the input has, e.g., only white space.
+
+Thu May 7 18:04:46 EDT 1992
+ dtoa.c: adjust treatment of exponent field (in strtod) to behave
+reasonably with huge numbers and 16-bit ints.
+
+Fri Jun 19 08:29:02 EDT 1992
+ dtoa.c: fix a botch in placement of #ifdef __cplusplus (which only
+matters if you're using a C++ compiler).
+
+Wed Oct 21 11:23:07 EDT 1992
+ dtoa.c: add #ifdef Bad_float_h lines for systems with missing or
+inferior float.h .
+
+Thu Apr 22 07:54:48 EDT 1993
+ dtoa.c: change < to <= in line 2059:
+< for(result_k = 0; sizeof(Bigint) - sizeof(unsigned long) + j < i;
+---
+> for(result_k = 0; sizeof(Bigint) - sizeof(unsigned long) + j <= i;
+With 32-bit ints, the former could give too small a block for the return
+value when, e.g., mode = 2 or 4 and ndigits = 24 (16 for 16-bit ints).
+
+Mon Jun 21 12:56:42 EDT 1993
+ dtoa.c: tweak to work with 32-bit ints and 64-bit longs
+when compiled with -DLong=int .
+
+Wed Jan 26 11:09:16 EST 1994
+ dtoa.c: fix bug in strtod's handling of numbers with very
+negative exponents (e.g. 1.8826e-512), which should underflow to 0;
+fix storage leak in strtod with underflows and overflows near
+the underflow and overflow thresholds.
+
+Mon Feb 28 11:37:30 EST 1994
+ dtoa.c:
+85a86,89
+> * #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.
+87a92,95
+> #ifndef MALLOC
+> #define MALLOC malloc
+> #endif
+>
+352c360
+< rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(Long));
+---
+> rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
+
+Thu Mar 3 16:56:39 EST 1994
+ dtoa.c: if MALLOC is #defined, declare it.
+
+Wed Jan 4 15:45:34 EST 1995
+ dtoa.c: add CONST qualification to tens, bigtens, tinytens (for use
+on embedded systems with little spare RAM).
+
+Fri Mar 1 08:55:39 EST 1996
+ g_fmt.c: honor the sign of 0 and return the first argument (buf).
+
+Sat Jul 6 07:59:28 EDT 1996
+ dtoa.c: cosmetic changes: "ULong" rather than "unsigned Long";
+update comments to reflect AT&T breakup.
+
+Mon Aug 5 23:31:24 EDT 1996
+ dtoa.c: add comment about invoking _control87(PC_53, MCW_PC)
+(or the equivalent) on 80x87 machines before calling strtod or dtoa.
+
+Tue Dec 17 15:01:56 EST 1996
+ dtoa.c: new #define possibilities: #define INFNAN_CHECK to have
+strtod check (case insensitively) for "Infinity" and "NaN" on machines
+with IEEE arithmetic; #define MULTIPLE_THREADS if the system offers
+preemptively scheduled multiple threads, in which case you must supply
+routines ACQUIRE_DTOA_LOCK(n) and FREE_DTOA_LOCK(n) (n = 0 or 1).
+New void freedtoa(char*) for freeing values returned by dtoa; use of
+freedtoa() is required if MULTIPLE_THREADS is #defined, and is merely
+recommended otherwise.
+ g_fmt.c: adjusted to invoke freedtoa().
+
+Wed Feb 12 00:40:01 EST 1997
+ dtoa.c: strtod: on IEEE systems, scale to avoid intermediate
+underflows when the result does not underflow; compiling with
+-DNO_IEEE_Scale restores the old logic. Fix a bug, revealed by
+input string 2.2250738585072012e-308, in treating input just less
+than the smallest normalized number. (The bug introduced an extra
+ULP of error in this special case.)
+
+Tue May 12 11:13:04 EDT 1998
+ dtoa.c: strtod: fix a glitch introduced with the scaling of 19970212
+that caused one-bit rounding errors in certain denormal numbers, such
+as 8.44291197326099e-309, which was read as 8.442911973260987e-309.
+Remove #ifdef Unsigned_Shifts logic in favor of unsigned arithmetic.
+Unless compiled with -DNO_LONG_LONG, use 64-bit arithmetic where
+possible.
+
+Fri May 15 07:49:07 EDT 1998
+ dtoa.c: strtod: fix another glitch with scaling to avoid underflow
+with IEEE arithmetic, again revealed by the input string
+2.2250738585072012e-308, which was rounded to the largest denormal
+rather than the smallest normal double precision number.
+
+Wed Aug 5 23:27:26 EDT 1998
+ gdtoa.tar.gz: tweaks in response to comments from Shawn C. Sheridan
+(with no effect on the resulting .o files except when strtod.c is
+compiled with -DNO_ERRNO); bigtens --> bigtens_D2A (a symbol meant
+to be private to gdtoa.a).
+
+Sat Sep 12 17:05:15 EDT 1998
+ gdtoa.tar.gz: more changes in response to comments from Shawn C.
+Sheridan (including repair of a glitch in g_ffmt.c). For consistency
+and possible convenience, there are some new functions and some name
+changes to existing ones:
+ Old New
+ --- g_xLfmt
+ strtoQ strtopQ
+ --- strtopd
+ strtodd strtopdd
+ --- strtopf
+ strtox strtopx
+ --- strtopxL
+ --- strtorxL
+ --- strtoIxL
+Functions strtopd and strtopf are variations of strtod and strtof,
+respectively, which write their results to their final (pointer)
+arguments. Functions strtorf and strtord are now analogous to the
+other strtor* functions in that they now have a final pointer
+argument to which they write their results, and they return the
+int value they get from strtodg.
+ The xL family (g_xLfmt, strto[Irp]xL) is a variation of the old x
+family (for 80-bit IEEE double-extended precision) that assumes the
+storage layout of the Motorola 68881's double-extended format: 80
+interesting bits stored in 3 unsigned 32-bit ints (with a "hole", 16
+zero bits, in the word that holds the sign and exponent). The x
+family now deals with 80-bit (5 unsigned 16-bit ints) rather than
+96-bit arrays (3 unsigned 32-bit ints) that hold its 80-bit
+double-extended values. (This relaxes the alignment requirements of
+the x family and results in strto[Ipr]x writing 80 rather than 96 bits
+to their final arguments.)
+ Each g_*fmt routine now returns a pointer to the null character
+that terminates the strings it writes, rather than a pointer to
+the beginning of that string (the first argument). These routines
+still return 0 (NULL) if the first argument is too short.
+ The second argument to g_dfmt is now pointer (to a double) rather
+than a double value.
+
+Thu Oct 29 21:54:00 EST 1998
+ dtoa.c: Fix bug in strtod under -DSudden_Underflow and (the default)
+-DAvoid_Underflow: some numbers that should have suffered sudden
+underflow were scaled inappropriately (giving nonzero return values).
+Example: "1e-320" gave -3.6304123742133376e+280 rather than 0.
+
+Mon Nov 2 15:41:16 EST 1998
+ dtoa.c: tweak to remove LL suffixes from numeric constants (for
+compilers that offer a 64-bit long long type but do not recognize the
+LL constants prescribed by C9x, the proposed update to the ANSI/ISO C
+standard). Thanks to Earl Chew for pointing out the existence of such
+compilers.
+ gdtoa.tar.gz: renamed gdtoa.tgz and updated to incorporate the above
+changes (of 29 Oct. and 2 Nov. 1998) to dtoa.c.
+
+Thu Mar 25 17:56:44 EST 1999
+ dtoa.c, gdtoa.tgz: fix a bug in strtod's reading of 4.9e-324:
+it returned 0 rather than the smallest denormal.
+
+Mon Apr 12 10:39:25 EDT 1999
+ gdtoa.tgz: test/ftest.c: change %.7g to %.8g throughout.
+
+Fri Aug 20 19:17:52 EDT 1999
+ gdtoa.tgz: gdtoa.c: fix two bugs reported by David Chase (thanks!):
+1. An adjustment for denormalized numbers around 503 was off by one.
+2. A check for "The special case" around line 551 omitted the condition
+that we not be at the bottom of the exponent range.
+
+Mon Sep 13 10:53:34 EDT 1999
+ dtoa.c: computationally invisible tweak for the benefit of people
+who actually read the code:
+
+2671c2671
+< && word0(d) & Exp_mask
+---
+> && word0(d) & (Exp_mask & Exp_mask << 1)
+
+I.e., in dtoa(), the "special case" does not arise for the smallest
+normalized IEEE double. Thanks to Waldemar Horwat for pointing this
+out and suggesting the modified test above. Also, some tweaks for
+compilation with -DKR_headers.
+ gdtoa.tgz: gdtoa.c: analogous change:
+
+552c552
+< if (bbits == 1 && be0 > fpi->emin) {
+---
+> if (bbits == 1 && be0 > fpi->emin + 1) {
+
+This has no effect on the g*fmt.c routines, but might affect the
+computation of the shortest decimal string that rounds to the
+smallest normalized floating-point number of other precisions.
+ gdota.tgz: test/d.out test/dI.out test/dd.out: updated to reflect
+previous changes (of 19990820); test/*.c: most test programs modified
+to permit #hex input. See the comments.
+
+Fri Sep 17 01:39:25 EDT 1999
+ Try again to update dtoa.c: somehow dtoa.c got put back to a version
+from 3 years ago after this "changes" file was updated on 13 Sept. 1999.
+One more tweak to omit a warning on some systems:
+2671c2671
+< && word0(d) & (Exp_mask & Exp_mask << 1)
+---
+> && word0(d) & (Exp_mask & ~Exp_msk1)
+Plus changes to avoid trouble with aggressively optimizing compilers
+(e.g., gcc 2.95.1 under -O2). On some systems, these changes do not
+affect the resulting machine code; on others, the old way of viewing
+a double as a pair of ULongs is available with -DYES_ALIAS.
+
+Tue Sep 21 09:21:25 EDT 1999
+ gdtoa.tgz: changes analogous to those of 17 Sept. 1999 to dtoa.c to
+avoid trouble with aggressively optimizing compilers.
+
+Wed Dec 15 13:14:38 EST 1999
+ dtoa.c: tweak to bypass a bug with HUGE_VAL on HP systems.
+
+Mon Jan 17 18:32:52 EST 2000
+ dtoa.c and gdtoa.tgz: strtod: set errno = ERANGE on all inputs that
+underflow to zero (not just those sufficiently less than the smallest
+positive denormalized number).
+ gdtoa.tgz: README: point out that compiling with -DNO_ERRNO inhibits
+errno assignments (by strtod and the core converter, strtodg).
+
+Tue Jan 18 16:35:31 EST 2000
+ dtoa.c and gdtoa.tgz: strtod: modify the test inserted yesterday so
+it may work correctly with buggy 80x87 compilers. (The change matters,
+e.g., to Microsoft Visual C++ 4.2 and 6.0.)
+
+Thu Nov 2 21:00:45 EST 2000
+ dtoa.c and gdtoa.tgz:
+1. Fix bug in test for exact half-way cases of denormalized numbers
+ (without -DNO_IEEE_Scale).
+2. Compilation with -DNO_ERRNO prevents strtod from assigning
+ errno = ERANGE when the result overflows or underflows to 0.
+3. With IEEE arithmetic and no -DNO_IEEE_Scale, adjust scaling so
+ ulp(d) never returns a denormalized number. This and other tweaks
+ permit strtod and dtoa to work correctly on machines that flush
+ underflows to zero but otherwise use IEEE arithmetic without
+ Sudden_Underflow being #defined (and with strtod simply returning 0
+ instead of denormalized numbers).
+4. Compilations with -DUSE_LOCALE causes strtod to use the current
+ locale's decimal_point value.
+5. Under compilations with -DINFNAN_CHECK, strtod and strtodg (case
+ insensitively) treat "inf" the same as "infinity" and, unless
+ compiled with -DNo_Hex_NaN, accept "nan(x)", where x is a string of
+ hexadecimal digits and spaces, as a NaN whose value is constructed
+ from x (as explained in comments near the top of dtoa.c and in
+ gdtoaimp.h).
+6. The default PRIVATE_MEM is increased slightly (to 2304), and comments
+ near the top of dtoa.c provide more discussion of PRIVATE_MEM.
+7. Meanings of dtoa modes 4,5,8,9 changed. See comments in dtoa.c and
+ gdtoa.c; modes 4 and 5 may now provide shorter strings that round
+ (in round-nearest mode) to the given double value. (Paxson's
+ testbase program is unhappy with this new rounding, as it can
+ introduce an error of more than one base-10 ulp when 17 or more
+ decimal digits are requested.)
+8. With IEEE arithmetic, compilation with -DHonor_FLT_ROUNDS causes
+ strtod and dtoa to round according to FLT_ROUNDS:
+ 0 ==> towards 0,
+ 1 ==> nearest,
+ 2 ==> towards +Infinity,
+ 3 ==> towards -Infinity.
+9. With IEEE arithmetic, compilation with -DSET_INEXACT causes extra
+ computation (and sometimes slower conversions in dtoa and strtod,
+ particularly for dtoa in cases where otherwise some simple floating-
+ point computations would suffice) to set the IEEE inexact flag
+ correctly. As comments in dtoa.c explain in more detail, this
+ requires compilation in an environment (such as #include "dtoa.c"
+ in suitable source) that provides
+ int get_inexact(void);
+ void clear_inexact(void);
+10. On input "-x", return 0 rather than -0.
+
+gdtoa.tgz: gethex.c: adjust logic for reading hex constants to accord
+with current wording of the C99 standard. Previously, I thought hex
+constants read by strtod and friends had to have either a decimal point
+or an exponent field; p. 307 of the C99 standard states that both are
+optional. Because of the complexity of this reading, it is available
+only in the variant of strtod that appears in gdtoa.tgz.
+
+strtodg (gdtoa.tgz): New return value STRTOG_NaNbits (with
+STRTOG_NoNumber renumbered). Allow STRTOG_Neg bit in strtodg returns
+for STRTOG_NaN and STRTOG_NaNbits.
+
+gdtoa.tgz: Fix uninitialized variable bug in g_Qfmt.c's handling of NaNs.
+
+Mon Nov 13 14:00:05 EST 2000
+ gdtoa.tgz: strtodg: fix a storage leak and an apparently rare infinite
+loop with a boundary case of directed rounding. Example input to
+gdtoa/test/Qtest where the loop bug bit:
+ r 3
+ 35184372088831.999999999999999999999999999999999999
+This was revealed by testbase for quad precision Solaris arithmetic;
+it did not show up in several other testbase configurations.
+
+Wed Feb 7 12:56:11 EST 2001
+ dtoa.c: fix bug (possible infinite loop, e.g., with
+2.47032822920623272e-324) introduced 20001113 in handling the special
+case of a power of 2 to be rounded down one ulp. Add test (required
+by changes of 20001113) for the extra special case of 2^-1075 (half
+the smallest denormal).
+ gdtoa.tgz: corresponding adjustments to strtod.c and strtodg.c.
+
+Tue Mar 13 00:46:09 EST 2001
+ gdtoa.tgz: gdtoa/strtodg.c: fix bug in handling values exactly half
+an ulp less than the smallest normal floating-point number;
+gdtoa/*test.c: fix glitch in handling "n ..." lines (intended to
+change "ndig").
+
+Wed Mar 6 10:13:52 EST 2002
+ gdtoa.tgz: add gdtoa/test/strtodt.c and gdtoa/test/testnos3 to test
+strtod on hard cases posted by Fred Tydeman to comp.arch.arithmetic on
+26 Feb. 1996. Add comment to gdtoa/README about strtod requiring true
+IEEE arithmetic (with 53-bit rounding precision on 80x87 chips).
+In gdtoa/test, automate selection of expected output files [xQ]*.out.
+
+Wed Mar 5 10:35:41 EST 2003
+ gdtoa.tgz: fix a bug in strtod's handling of 0-valued 0x... "decimal"
+strings. A fault was possible. Thanks to David Shultz for reporting
+this bug.
+
+Tue Mar 18 09:38:28 EST 2003
+ gdtoa.tgz: fix a glitch in strtodg.c with -DUSE_LOCALE; add #ifdef
+USE_LOCALE lines to g__fmt.c (to affect binary --> decimal conversions
+via the g*fmt routines), and add comments about -DUSE_LOCALE to README.
+In short, compiling strtod.c, strtodg.c, and g__fmt.c with -DUSE_LOCALE
+causes them to determine the decimal-point character from the current
+locale. (Otherwise it is '.'.)
+
+Fri Mar 21 16:36:27 EST 2003
+ gdtoa.tgz: gethex.c: add #ifdef USE_LOCAL logic; strtod.c: fix a
+glitch in handling 0x... input (the return from gethex was ignored).
+
+Wed Mar 26 15:35:10 EST 2003
+ gdtoa.tgz: gethex.c: pedantic (and normally invisible) change:
+use unsigned char for decimalpoint variable (under -DUSE_LOCALE).
+
+Sat Jan 17 23:58:52 MST 2004
+ gdtoa.tgz: gethex.c: supply missing parens in test for whether a
+denormal result should be zero, correct logic for rounding up when the
+result is denormal, and when returning zero or Infinity, set *bp = 0;
+strtod.c: switch on gethex(...) & STRTOG_Retmask rather than just on
+gethex(), and only copybits(..., bb) when bb is nonzero. This
+mattered for underflows and overflows in 0x notation.
+
+Thu Mar 25 22:34:56 MST 2004
+ dtoa.c and gdtoa.c/misc.c: change "(!x & 1)" to "(!x)" to avoid
+confusion by human readers -- the object code is unaffected (with
+reasonable compilers).
+
+Mon Apr 12 00:44:22 MDT 2004
+ dtoa.c and gdtoa.tar.gz: update contact info. for dmg and correct
+page numbers in comment on Steele & White (1990).
+ gdtoa.tgz: add strtodnrp.c for a variant of strtod that is slower
+but does not require 53-bit rounding precision on Intel IA32 systems.
+
+Tue Apr 13 00:28:14 MDT 2004
+ gdtoa.tgz: strtod.c: fix glitch when both INFNAN_CHECK and No_Hex_NaN
+are #defined. Thanks to David Mendenhall for pointing this bug out.
+
+Wed Jan 5 22:39:17 MST 2005
+ gdtoa.tgz:
+ gethex.c: fix the bug reported by Stefan Farfeleder of ignoring a
+binary-exponent-part if the converted number is zero.
+ strto[pr]x.c: fix bug reported by Stefan Farfeleder in setting the
+exponent of denormals (which should be 0, not 1).
+ g_xfmt.c: fix a corresponding bug with denormals.
+ strtodg.c: fix a bug under IBM (base 16) arithemtic reported
+by Greg Alexander: a correction to the binary exponent for changes to
+the exponent of a native double value for avoiding overflow had to be
+multiplied by 4 ("e2 <<= 2;").
+ Various files: minor tweaks for portability.
+
+Sat Jan 15 15:36:03 MST 2005
+ gdtoa.tgz: gethex.c: fix a glitch introduced last week (and reported
+by Stefan Farfelder) with 0x forms with no nonzero digits before the "."
+character, e.g., 0x.1 (which was rendered as 0 rather than .0625).
+ gdtoa.tgz: many files: add automatic computation of gd_qnan.h for
+giving the system-dependent format of a quiet NaN (the one generated
+for Infinity - Infinity). Tweak test/makefile so differences in the
+spelling of Infinity ("INF" or "Inf" on some systems) do not matter.
+Fix bug in strtod.c and strtodg.c under which, e.g., -.nan was read
+as NaN rather than unacceptable input (causing return 0). Adjust
+comments in README about nan(...). Fix glitch in test/dt.c.
+
+Sun Jan 16 18:22:13 MST 2005
+ gdtoa.tgz: strtodg.c: fix long-standing bug in handling input
+that rounds up to 2^nbits, e.g., strtof("16777215.5"). Thanks to
+Edward Moy for reporting this problem.
+ gdtoa.tgz: Fix some bugs with -DJust_16.
+
+Thu Sep 22 22:40:16 MDT 2005
+gdtoa.tgz:
+ strtod.c: unless prevented by -DNO_FENV_H, include C99's fenv.h
+and with hex input, get the current rounding mode from fegetround().
+With decimal input, strtod honors the rounding mode automatically.
+Thanks to David Schultz (das at FreeBSD dot ORG) for pointing
+ strtodg.c: fix a bug with handling numbers very near the largest
+possible one, which were sometimes incorrectly converted to Infinity.
+Thanks to Edward Moy (emoy at apple dot com) for pointing this out.
+ g_Qfmt.c: change strcpy to strcp. Thanks to J. T. Conklin
+(jtc at acorntoolworks dot com) for pointing this out.
+ test/xtest.c: fix some subscript bugs.
+ test/x.ou0, test/x.ou1, test/xL.: update in response to the above fix to
+test/xtest.c.
+ test/makefile: add -lm to some link lines (needed for fegetround).
+
+Sun Jan 21 20:26:44 MST 2007
+gdtoa.tgz:
+ strtodg.c: fix a botch in the test of whether to increase rvbits
+before terminating the big for(;;) loop with dsign true: change
+ if (hi0bits(rvb->x[(rvb->wds - 1) >> kshift])
+ != j)
+ rvbits++;
+to
+ if (hi0bits(rvb->x[rvb->wds - 1]) != j)
+ rvbits++;
+Example of input where this bug bit: 1.9e27. Thanks to Edward Moy
+<emoy@apple.com> for providing this example. Also, simplify the
+preceding computation of j.
+ test/README: add comment that strtodt needs to operate with 53-bit
+rounding precision on Intel x86 systems, and add a pointer to Paxson's
+paper.
+
+Sat Mar 15 11:44:31 MDT 2008
+ dtoa.c and gdtoa.tgz: with -DINFNAN_CHECK and without
+-DGDOTA_NON_PEDANTIC_NANCHECK, conform to the ill-advised prescription
+in the C99 standard of consuming (...) in "nan(...)" even when ...
+is not of the expected form. Allow an optional 0x or 0X to precede
+the string of hex digits in the expected form of ... .
+ gdtoa.tgz: gethex.c: have, e.g., strtod("0xyz",&se) set se to "xyz".
+Previously it was incorrectly set to "0xyz".
+
+Thu Aug 28 22:37:35 MDT 2008
+ dtoa.c and gdtoa.tgz: Fix a bug in strtod when compiled with
+-DHonor_FLT_ROUNDS: in rounding modes other than "to nearest",
+strtod looped on input larger than and within a factor of 2 of
+the largest finite floating-point number. Since FLT_ROUNDS is buggy
+on some (Linux) systems in that it does not reflect calls on
+fesetround(), when Honor_FLT_ROUNDS is #defined, get the curren
+rounding mode from fegetround() rather than FLT_ROUNDS, unless
+Trust_FLT_ROUNDS is also #defined.
+ gdtoa/test/getround.c in gdtoa.tgz: simply report the current
+rounding mode when the input line is "r" by itself. (Previously it
+did so, but also complained of invalid input.)
+ gdtoa/gethex.c: fix an off-by-one bug in a rounding test; detect and
+deal with huge exponents (positive or negative). This affected the
+reading of hexadecimal floating-point values (0x...). Also set errno
+to ERANGE on out-of-range values (unless compiled with -DNO_ERRNO).
+ gdtoa/strtod.c: adjust scaling of tinytens[4] (as in dtoa.c) to
+avoid double rounding when dealing with numbers near the bottom of
+the exponent range.
+
+Sat Aug 30 23:37:07 MDT 2008
+ gdtoa/gethex.c: ensure *bp is set to something (NULL if nothing else).
+ Bring gdtoa/xsum0.out and gdtoa/test/xsum0.out up to date.
+
+Tue Sep 9 22:08:30 MDT 2008
+ gdtoa/strto*.c and gdtoa/*fmt.c: if compiled with -DUSE_LOCALE, use
+the current locale's decimal point character string.
+ gdtoa/gdtoa.c: trim trailing zeros in a missed case (e.g., ndigits = 6
+on 1020302).
+ dtoa.c and gdtoa/strtod.c: on systems with IEEE arithmetic (and without
+NO_ERRNO being defined) set ERANGE for denormal values as well as real
+underflows.
+ gdtoa/strtodg.c: fix an off-by-one bug in rounding to the largest
+representable magnitude when nbits is a multiple of 32.
+ gdtoa/*fmt.c and gdtoa/gdtoa.h: bufsize changed from unsigned to size_t.
+ gdtoaimp.h, *fmt.c: change in calling sequence to internal g__fmt(),
+which now explicitly checks bufsize.
+ Relevant routines (see README) honor the current rounding mode if
+compiled with -DHonor_FLT_ROUNDS on IEEE-arithmetic systems that provide
+the C99 fegetround() function.
+ gdtoa/test/getround.c can optionally be compiled with
+-DHonor_FLT_ROUNDS and/or -DUSE_MY_LOCALE for manual testing of gdtoa.a
+compiled with -DHonor_FLT_ROUNDS or -DUSE_LOCALE.
+
+Fri Oct 10 20:07:15 MDT 2008
+ gdtoa/gethex.c: fix a bug reading hexadecimal floating-point values
+starting with "0xd" for a nonzero digit d (such as "0x1.0002p3"). The
+bug caused the values to be read as zero with endptr set incorrectly.
+
+Tue Oct 28 00:14:08 MDT 2008
+ gdtoa/strtod.c: fix a comment glitch (with commented {}).
+
+Tue Nov 11 23:05:25 MST 2008
+ gdtoa: fix a glitch in the strto* routines when compiled with
+-DUSE_LOCALE and the locale's decimal-point string is two or more
+characters long. Wrong conversions were then possible.
+
+Fri Dec 5 18:20:36 MST 2008
+ gdtoa.tgz: fix bugs with reading C99-style hexadecimal floating-point
+values when compiled with -DPack_16; on IEEE-arithmetic systems, make
+INFNAN_CHECK the default unless NO_INFNAN_CHECK is #defined. (This is
+consistent with dtoa.c, which has worked this way for a while.)
+ dtoa.c: add recognition of C99-style hexadecimal floating-point
+values (unless compiled with NO_HEX_FP is #defined).
+
+Thu Dec 11 23:10:23 MST 2008
+ dtoa.c: omit an unused variable.
+
+Fri Jan 2 22:45:33 MST 2009
+ dtoa.c: tweak to banish some compiler warnings.
+
+Sun Mar 1 20:57:22 MST 2009
+ dtoa.c, gdtoa/{g__fmt.c, gethex.c, strtod.c, strtodg.c}: change malloc
+to MALLOC.
+ dtoa.c and gdtoa/gdtoaimp.h and gdtoa/misc.c: reduce Kmax, and use
+MALLOC and FREE or free for huge blocks, which are possible only in
+pathological cases, such as dtoa calls in mode 3 with thousands of
+digits requested, or strtod() calls with thousand of digits. For the
+latter case, I have an alternate approach that runs much faster
+and uses less memory, but finding time to get it ready for distribution
+may take a while.
+
+Mon Mar 16 00:32:43 MDT 2009
+ dtoa.c: Fix a bug under -DUSE_LOCALE in handling "decimal point"
+strings more than one character long.
+ dtoa.c and gdtoa/misc.c: Remove a buggy test activated with
+-DDEBUG.
+ dtoa.c and gdtoa/gdtoa.c: simplify logic for "4 leading 0 bits".
+ dtoa.c: Add logic (that can be disabled with -DNO_STRTOD_BIGCOMP
+and that) to strtod for more efficiently handling a very long input
+string. It proceeds by initially truncating the input string, then if
+necessary comparing the whole string with a decimal expansion to
+decide close cases. This logic is only used for input more than
+STRTOD_DIGLIM digits long (default 40), and for now only applies to
+IEEE arithmetic (for want of other kinds of platforms on which to run
+tests). This only appears worthwhile for absurdly long input strings,
+so a corresponding update to gdtoa does not seem warranted.
+ dtoa.c, gdtoa.tgz: tweaks (mostly adding unnecessary parens) to
+silence "gcc -Wall" warnings. Aside from a couple of minor changes
+to banish erroneous warnings about uninitialized variables, the tweaks
+do not affect the generated object code.
+
+Sat Apr 11 23:25:58 MDT 2009
+ dtoa.c: fix glitch in compiling with -DNo_Hex_NaN and the bug of
+accepting (e.g.) ".nan" or ".inf" as NaN or Infinity.
+ gdtoa.tgz: tweaks to silence warnings from "gcc -Wstrict-aliasing=2";
+update xsum0.out files.
+
+Sun Apr 19 23:40:24 MDT 2009
+ dtoa.c, gdtoa/misc.c: do not attempt to allocate large memory blocks
+from the private memory pool (which was an unlikely event, but a bug).
+ gdtoa/strtopx.c, gdtoa/strtopxL.c, gdtoa/strtorx.c, gdtoa/strtorxL.c:
+supply explicit bit for Infinity. Note that the Q routines (which do
+not supply this bit) are appropriate for Sparc quad precision (probably
+known as long double with most current compilers).
+
+Wed Dec 9 08:14:52 MST 2009
+ gdtoa.tgz: add gdtoa/printf.c* and modify makefile so "make Printf"
+adds a printf to gdtoa.a (to be accessed with #include "stdio1.h" to
+get gdtoa/stdio1.h, which you might install in some standard place).
+On Intel/AMD i386, x86_64, and Sparc systems, this adds formats %La,
+%Le, %Lf and %Lg to handle long double. On x86_64 systems, it also
+adds %Lqa, %Lqe, %Lqf and %Lqg to handle 128-bit bit types (called
+__float128 by gcc and _Quad by the Intel compiler). In gdtoa/test,
+"make pf_test" tests this printf (provided the system is an i386,
+x86_64, or Sparc system). On x86_64 systems, "make pf_testLq" tests
+the %Lq... formats (briefly).
+
+Mon Jan 11 22:25:17 MST 2010
+ dtoa.c: fix a minor performance bug and, under compilation with -DDEBUG,
+an erroneous error message "oversize b in quorem" in strtod's processing
+of some input that underflows to zero. Also fix a bug in bigcomp()'s
+handling of numbers that will scale to denormal values. The increments
+that bigcomp applied were ignoring the effects of denormalization.
+
+Sat Jan 23 00:25:54 MST 2010
+ dtoa.c: Fix some glitches in recently introduced changes meant to
+speed up returns in pedantic cases. In quorem, adjust #ifdef DEBUG
+stuff so it does not complain when bigcomp() calls quorem on input
+near the smallest representable number and rounding up by a bit causes
+a quorem return > 9 (which in this case is not a bug). Fix a memory
+leak in the unlikely case of overflow only being detected after some
+high-precision integer computations. Fix an off-by-one bug in
+handling a large number of digits with a few nonzero digits, followed
+by many zeros, and then some nonzero digits. (This does not happen
+with sensible input.) Fix an off-by-one bug in a recently introduced
+quick test for underflow (i.e., zero result) on input at the bottom of
+the exponent range. Thanks to Mark Dickinson for pointing these bugs
+out.
+
+ dtoa.c and gdtoa/strtod.c: Fix an obscure bug in strtod's handling
+of some inputs of many digits at the bottom of the exponent range:
+results were sometimes off by a bit when gdtoa/strtod.c or dtoa.c was
+compiled without -DNO_IEEE_SCALE and, for dtoa.c, when compiled with
+-DNO_STRTOD_BIGCOMP.
+
+ gdtoa/test/testnos3: add some examples that went wrong before
+the present changes.
+
+Sat Jan 23 23:29:02 MST 2010
+ dtoa.c: more tweaks relevant only to absurd input.
+
+Tue Feb 2 23:05:34 MST 2010
+ dtoa.c: add test for setting errno = ERANGE when input of many digits
+is rounded to Infinity or underflows to zero. Fix a memory leak in
+such instances.
+ gdtoa/strtod.c: make some corresponding changes.
+
+Wed Jul 7 09:25:46 MDT 2010
+ dtoa.c: adjust to use bigcomp when necessary when compiled with
+-DHonor_FLT_ROUNDS (and without -DNO_STRTOD_BIGCOMP), and the rounding
+mode is torwards +Infinity. An input (supplied by Rick Regan
+<exploringbinary@gmail.com>) where this matters is
+1.100000000000000088817841970012523233890533447265626
+ gdtoa/strtod.c: fix errors (introduced 20090411) when compiled
+with -DHonor_FLT_ROUNDS.
+
+Wed Sep 15 09:00:26 MDT 2010
+ dtoa.c, gdtoa/dtoa.c, gdtoa/gdtoa.c: fix bugs with -DROUND_BIASED
+pointed out by Jay Foad.
+
+Mon Sep 27 13:43:30 MDT 2010
+ gdtoa/gdtoa.c: fix a glitch (not revealed by compilation) in the
+changes of 15 Sept. 2010.
+
+Fri Nov 5 13:02:41 MDT 2010
+ dtoa.c: fix a bug related to bigcomp: decimal strings with all
+zeros before the decimal point more than 40 significant digits that
+required use of bigcomp might be converted very incorrectly.
+Example: .010000000000000000057612911342378542997169 .
+Thanks to Rick Regan <exploringbinary@gmail.com> for reporting the
+symptoms and providing an example.
+
+20110403:
+ dtoa.c, gdtoa/gdtoaimp.h, gdtoa/strtod.c: if
+ROUND_BIASED_without_Round_Up is #defined, assume ROUND_BIASED and
+omit the quick computation that would use ordinary arithmetic to
+compute the correctly rounded result with one rounding error. If you
+want biased rounding with IEEE-style format "double" and will operate
+with rounding toward +Infinity, it suffices to #define ROUND_BIASED
+(and thus retain the quick computation when it is appropriate).
+ gdtoa/gdtoa.h: change default Long from long to int (with the goal
+of portability when compiling without -DLong=... specified). On some
+64-bit systems, long is a 64-bit type; we need a 32-bit type here.
+ dtoa.c, gdtoa/gdtoa.c: fix a glith with ndigits with mode = 4 at
+the bottom of the exponent range, e.g., 1e-323.
diff --git a/contrib/gdtoa/dtoa.c b/contrib/gdtoa/dtoa.c
index 48fdf5e..6e5de30 100644
--- a/contrib/gdtoa/dtoa.c
+++ b/contrib/gdtoa/dtoa.c
@@ -75,10 +75,10 @@ THIS SOFTWARE.
char *
dtoa
#ifdef KR_headers
- (d, mode, ndigits, decpt, sign, rve)
- double d; int mode, ndigits, *decpt, *sign; char **rve;
+ (d0, mode, ndigits, decpt, sign, rve)
+ double d0; int mode, ndigits, *decpt, *sign; char **rve;
#else
- (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+ (double d0, int mode, int ndigits, int *decpt, int *sign, char **rve)
#endif
{
/* Arguments ndigits, decpt, sign are similar to those
@@ -124,7 +124,8 @@ dtoa
ULong x;
#endif
Bigint *b, *b1, *delta, *mlo, *mhi, *S;
- double d2, ds, eps;
+ U d, d2, eps;
+ double ds;
char *s, *s0;
#ifdef SET_INEXACT
int inexact, oldinexact;
@@ -149,35 +150,35 @@ dtoa
dtoa_result = 0;
}
#endif
-
- if (word0(d) & Sign_bit) {
+ d.d = d0;
+ if (word0(&d) & Sign_bit) {
/* set sign for everything, including 0's and NaNs */
*sign = 1;
- word0(d) &= ~Sign_bit; /* clear sign bit */
+ 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)
+ if ((word0(&d) & Exp_mask) == Exp_mask)
#else
- if (word0(d) == 0x8000)
+ if (word0(&d) == 0x8000)
#endif
{
/* Infinity or NaN */
*decpt = 9999;
#ifdef IEEE_Arith
- if (!word1(d) && !(word0(d) & 0xfffff))
+ 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 */
+ dval(&d) += 0; /* normalize */
#endif
- if (!dval(d)) {
+ if (!dval(&d)) {
*decpt = 1;
return nrv_alloc("0", rve, 1);
}
@@ -196,26 +197,26 @@ dtoa
}
#endif
- b = d2b(dval(d), &be, &bbits);
+ b = d2b(dval(&d), &be, &bbits);
#ifdef Sudden_Underflow
- i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+ i = (int)(word0(&d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
#else
- if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) {
+ 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;
+ 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;
+ 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)
+ * log10(&d) = (i-Bias)*log(2)/log(10) + log10(&d2)
*
- * This suggests computing an approximation k to log10(d) by
+ * This suggests computing an approximation k to log10(&d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
@@ -244,21 +245,21 @@ dtoa
/* 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 */
+ 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;
+ 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])
+ if (dval(&d) < tens[k])
k--;
k_check = 0;
}
@@ -297,10 +298,11 @@ dtoa
try_quick = 0;
}
leftright = 1;
+ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
+ /* silence erroneous "gcc -Wall" warning. */
switch(mode) {
case 0:
case 1:
- ilim = ilim1 = -1;
i = 18;
ndigits = 0;
break;
@@ -334,7 +336,7 @@ dtoa
/* Try to get by with floating-point arithmetic. */
i = 0;
- dval(d2) = dval(d);
+ dval(&d2) = dval(&d);
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
@@ -344,7 +346,7 @@ dtoa
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
- dval(d) /= bigtens[n_bigtens-1];
+ dval(&d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
@@ -352,32 +354,32 @@ dtoa
ieps++;
ds *= bigtens[i];
}
- dval(d) /= ds;
+ dval(&d) /= ds;
}
else if (( j1 = -k )!=0) {
- dval(d) *= tens[j1 & 0xf];
+ dval(&d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
- dval(d) *= bigtens[i];
+ dval(&d) *= bigtens[i];
}
}
- if (k_check && dval(d) < 1. && ilim > 0) {
+ if (k_check && dval(&d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
- dval(d) *= 10.;
+ dval(&d) *= 10.;
ieps++;
}
- dval(eps) = ieps*dval(d) + 7.;
- word0(eps) -= (P-1)*Exp_msk1;
+ 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))
+ dval(&d) -= 5.;
+ if (dval(&d) > dval(&eps))
goto one_digit;
- if (dval(d) < -dval(eps))
+ if (dval(&d) < -dval(&eps))
goto no_digits;
goto fast_failed;
}
@@ -386,34 +388,34 @@ dtoa
/* Use Steele & White method of only
* generating digits needed.
*/
- dval(eps) = 0.5/tens[ilim-1] - dval(eps);
+ dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
for(i = 0;;) {
- L = dval(d);
- dval(d) -= L;
+ L = dval(&d);
+ dval(&d) -= L;
*s++ = '0' + (int)L;
- if (dval(d) < dval(eps))
+ if (dval(&d) < dval(&eps))
goto ret1;
- if (1. - dval(d) < dval(eps))
+ if (1. - dval(&d) < dval(&eps))
goto bump_up;
if (++i >= ilim)
break;
- dval(eps) *= 10.;
- dval(d) *= 10.;
+ 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))
+ 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))
+ if (dval(&d) > 0.5 + dval(&eps))
goto bump_up;
- else if (dval(d) < 0.5 - dval(eps)) {
+ else if (dval(&d) < 0.5 - dval(&eps)) {
while(*--s == '0');
s++;
goto ret1;
@@ -426,7 +428,7 @@ dtoa
#endif
fast_failed:
s = s0;
- dval(d) = dval(d2);
+ dval(&d) = dval(&d2);
k = k0;
ilim = ilim0;
}
@@ -438,22 +440,22 @@ dtoa
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
- if (ilim < 0 || dval(d) <= 5*ds)
+ 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;
+ 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) {
+ if (dval(&d) < 0) {
L--;
- dval(d) += ds;
+ dval(&d) += ds;
}
#endif
*s++ = '0' + (int)L;
- if (!dval(d)) {
+ if (!dval(&d)) {
#ifdef SET_INEXACT
inexact = 0;
#endif
@@ -467,8 +469,13 @@ dtoa
case 2: goto bump_up;
}
#endif
- dval(d) += dval(d);
- if (dval(d) > ds || dval(d) == ds && L & 1) {
+ dval(&d) += dval(&d);
+#ifdef ROUND_BIASED
+ if (dval(&d) >= ds)
+#else
+ if (dval(&d) > ds || (dval(&d) == ds && L & 1))
+#endif
+ {
bump_up:
while(*--s == '9')
if (s == s0) {
@@ -533,9 +540,9 @@ dtoa
&& Rounding == 1
#endif
) {
- if (!word1(d) && !(word0(d) & Bndry_mask)
+ if (!word1(&d) && !(word0(&d) & Bndry_mask)
#ifndef Sudden_Underflow
- && word0(d) & (Exp_mask & ~Exp_msk1)
+ && word0(&d) & (Exp_mask & ~Exp_msk1)
#endif
) {
/* The special case */
@@ -621,7 +628,7 @@ dtoa
j1 = delta->sign ? 1 : cmp(b, delta);
Bfree(delta);
#ifndef ROUND_BIASED
- if (j1 == 0 && mode != 1 && !(word1(d) & 1)
+ if (j1 == 0 && mode != 1 && !(word1(&d) & 1)
#ifdef Honor_FLT_ROUNDS
&& Rounding >= 1
#endif
@@ -638,11 +645,11 @@ dtoa
goto ret;
}
#endif
- if (j < 0 || j == 0 && mode != 1
+ if (j < 0 || (j == 0 && mode != 1
#ifndef ROUND_BIASED
- && !(word1(d) & 1)
+ && !(word1(&d) & 1)
#endif
- ) {
+ )) {
if (!b->x[0] && b->wds <= 1) {
#ifdef SET_INEXACT
inexact = 0;
@@ -659,7 +666,11 @@ dtoa
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
- if ((j1 > 0 || j1 == 0 && dig & 1)
+#ifdef ROUND_BIASED
+ if (j1 >= 0 /*)*/
+#else
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+#endif
&& dig++ == '9')
goto round_9_up;
}
@@ -719,7 +730,12 @@ dtoa
#endif
b = lshift(b, 1);
j = cmp(b, S);
- if (j > 0 || j == 0 && dig & 1) {
+#ifdef ROUND_BIASED
+ if (j >= 0)
+#else
+ if (j > 0 || (j == 0 && dig & 1))
+#endif
+ {
roundoff:
while(*--s == '9')
if (s == s0) {
@@ -730,7 +746,9 @@ dtoa
++*s++;
}
else {
+#ifdef Honor_FLT_ROUNDS
trimzeros:
+#endif
while(*--s == '0');
s++;
}
@@ -745,9 +763,9 @@ dtoa
#ifdef SET_INEXACT
if (inexact) {
if (!oldinexact) {
- word0(d) = Exp_1 + (70 << Exp_shift);
- word1(d) = 0;
- dval(d) += 1.;
+ word0(&d) = Exp_1 + (70 << Exp_shift);
+ word1(&d) = 0;
+ dval(&d) += 1.;
}
}
else if (!oldinexact)
diff --git a/contrib/gdtoa/g__fmt.c b/contrib/gdtoa/g__fmt.c
index fbccb7d..6c4b3d2 100644
--- a/contrib/gdtoa/g__fmt.c
+++ b/contrib/gdtoa/g__fmt.c
@@ -56,7 +56,7 @@ g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
dlen = strlen(s0);
- if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
diff --git a/contrib/gdtoa/g_ddfmt.c b/contrib/gdtoa/g_ddfmt.c
index b65d39d..1256655 100644
--- a/contrib/gdtoa/g_ddfmt.c
+++ b/contrib/gdtoa/g_ddfmt.c
@@ -33,9 +33,9 @@ THIS SOFTWARE.
char *
#ifdef KR_headers
-g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; size_t bufsize;
+g_ddfmt(buf, dd0, ndig, bufsize) char *buf; double *dd0; int ndig; size_t bufsize;
#else
-g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
+g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
#endif
{
FPI fpi;
@@ -43,7 +43,7 @@ g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
ULong *L, bits0[4], *bits, *zx;
int bx, by, decpt, ex, ey, i, j, mode;
Bigint *x, *y, *z;
- double ddx[2];
+ U *dd, ddx[2];
#ifdef Honor_FLT_ROUNDS /*{{*/
int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
@@ -63,7 +63,8 @@ g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
if (bufsize < 10 || bufsize < ndig + 8)
return 0;
- L = (ULong*)dd;
+ dd = (U*)dd0;
+ L = dd->L;
if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) {
/* Infinity or NaN */
if (L[_0] & 0xfffff || L[_1]) {
@@ -88,7 +89,7 @@ g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
goto nanret;
goto infret;
}
- if (dd[0] + dd[1] == 0.) {
+ if (dval(&dd[0]) + dval(&dd[1]) == 0.) {
b = buf;
#ifndef IGNORE_ZERO_SIGN
if (L[_0] & L[2+_0] & 0x80000000L)
@@ -99,16 +100,16 @@ g_ddfmt(char *buf, double *dd, int ndig, size_t bufsize)
return b;
}
if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) {
- ddx[1] = dd[0];
- ddx[0] = dd[1];
+ dval(&ddx[1]) = dval(&dd[0]);
+ dval(&ddx[0]) = dval(&dd[1]);
dd = ddx;
- L = (ULong*)dd;
+ L = dd->L;
}
- z = d2b(dd[0], &ex, &bx);
- if (dd[1] == 0.)
+ z = d2b(dval(&dd[0]), &ex, &bx);
+ if (dval(&dd[1]) == 0.)
goto no_y;
x = z;
- y = d2b(dd[1], &ey, &by);
+ y = d2b(dval(&dd[1]), &ey, &by);
if ( (i = ex - ey) !=0) {
if (i > 0) {
x = lshift(x, i);
diff --git a/contrib/gdtoa/g_dfmt.c b/contrib/gdtoa/g_dfmt.c
index 23d8b24..8367868 100644
--- a/contrib/gdtoa/g_dfmt.c
+++ b/contrib/gdtoa/g_dfmt.c
@@ -88,6 +88,8 @@ g_dfmt(char *buf, double *d, int ndig, size_t bufsize)
if (ndig <= 0)
mode = 0;
i = STRTOG_Normal;
+ if (sign)
+ i = STRTOG_Normal | STRTOG_Neg;
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
return g__fmt(buf, s, se, decpt, sign, bufsize);
}
diff --git a/contrib/gdtoa/gdtoa.c b/contrib/gdtoa/gdtoa.c
index 3b64250..e15bb2a 100644
--- a/contrib/gdtoa/gdtoa.c
+++ b/contrib/gdtoa/gdtoa.c
@@ -123,6 +123,7 @@ gdtoa
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.
+ be = exponent: value = (integer represented by bits) * (2 to the power of be).
mode:
0 ==> shortest string that yields d when read in
@@ -157,8 +158,9 @@ gdtoa
int rdir, s2, s5, spec_case, try_quick;
Long L;
Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
- double d, d2, ds, eps;
+ double d2, ds;
char *s, *s0;
+ U d, eps;
#ifndef MULTIPLE_THREADS
if (dtoa_result) {
@@ -197,21 +199,21 @@ gdtoa
return nrv_alloc("0", rve, 1);
}
- dval(d) = b2d(b, &i);
+ dval(&d) = b2d(b, &i);
i = be + bbits - 1;
- word0(d) &= Frac_mask1;
- word0(d) |= Exp_11;
+ word0(&d) &= Frac_mask1;
+ word0(&d) |= Exp_11;
#ifdef IBM
- if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
- dval(d) /= 1 << j;
+ 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)
+ * log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2)
*
- * This suggests computing an approximation k to log10(d) by
+ * This suggests computing an approximation k to log10(&d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
@@ -231,7 +233,7 @@ gdtoa
i <<= 2;
i += j;
#endif
- ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
/* correct assumption about exponent range */
if ((j = i) < 0)
@@ -246,13 +248,13 @@ gdtoa
#ifdef IBM
j = be + bbits - 1;
if ( (j1 = j & 3) !=0)
- dval(d) *= 1 << j1;
- word0(d) += j << Exp_shift - 2 & Exp_mask;
+ dval(&d) *= 1 << j1;
+ word0(&d) += j << Exp_shift - 2 & Exp_mask;
#else
- word0(d) += (be + bbits - 1) << Exp_shift;
+ word0(&d) += (be + bbits - 1) << Exp_shift;
#endif
if (k >= 0 && k <= Ten_pmax) {
- if (dval(d) < tens[k])
+ if (dval(&d) < tens[k])
k--;
k_check = 0;
}
@@ -282,11 +284,14 @@ gdtoa
mode -= 4;
try_quick = 0;
}
+ else if (i >= -4 - Emin || i < Emin)
+ try_quick = 0;
leftright = 1;
+ ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
+ /* silence erroneous "gcc -Wall" warning. */
switch(mode) {
case 0:
case 1:
- ilim = ilim1 = -1;
i = (int)(nbits * .30103) + 3;
ndigits = 0;
break;
@@ -328,10 +333,10 @@ gdtoa
/* Try to get by with floating-point arithmetic. */
i = 0;
- d2 = dval(d);
+ d2 = dval(&d);
#ifdef IBM
- if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0)
- dval(d) /= 1 << j;
+ if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
+ dval(&d) /= 1 << j;
#endif
k0 = k;
ilim0 = ilim;
@@ -342,7 +347,7 @@ gdtoa
if (j & Bletch) {
/* prevent overflows */
j &= Bletch - 1;
- dval(d) /= bigtens[n_bigtens-1];
+ dval(&d) /= bigtens[n_bigtens-1];
ieps++;
}
for(; j; j >>= 1, i++)
@@ -354,30 +359,30 @@ gdtoa
else {
ds = 1.;
if ( (j1 = -k) !=0) {
- dval(d) *= tens[j1 & 0xf];
+ dval(&d) *= tens[j1 & 0xf];
for(j = j1 >> 4; j; j >>= 1, i++)
if (j & 1) {
ieps++;
- dval(d) *= bigtens[i];
+ dval(&d) *= bigtens[i];
}
}
}
- if (k_check && dval(d) < 1. && ilim > 0) {
+ if (k_check && dval(&d) < 1. && ilim > 0) {
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
- dval(d) *= 10.;
+ dval(&d) *= 10.;
ieps++;
}
- dval(eps) = ieps*dval(d) + 7.;
- word0(eps) -= (P-1)*Exp_msk1;
+ 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))
+ dval(&d) -= 5.;
+ if (dval(&d) > dval(&eps))
goto one_digit;
- if (dval(d) < -dval(eps))
+ if (dval(&d) < -dval(&eps))
goto no_digits;
goto fast_failed;
}
@@ -386,38 +391,38 @@ gdtoa
/* Use Steele & White method of only
* generating digits needed.
*/
- dval(eps) = ds*0.5/tens[ilim-1] - dval(eps);
+ dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps);
for(i = 0;;) {
- L = (Long)(dval(d)/ds);
- dval(d) -= L*ds;
+ L = (Long)(dval(&d)/ds);
+ dval(&d) -= L*ds;
*s++ = '0' + (int)L;
- if (dval(d) < dval(eps)) {
- if (dval(d))
+ if (dval(&d) < dval(&eps)) {
+ if (dval(&d))
inex = STRTOG_Inexlo;
goto ret1;
}
- if (ds - dval(d) < dval(eps))
+ if (ds - dval(&d) < dval(&eps))
goto bump_up;
if (++i >= ilim)
break;
- dval(eps) *= 10.;
- dval(d) *= 10.;
+ 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;
+ 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))
+ if (dval(&d) > ds + dval(&eps))
goto bump_up;
- else if (dval(d) < ds - dval(eps)) {
- if (dval(d))
+ else if (dval(&d) < ds - dval(&eps)) {
+ if (dval(&d))
inex = STRTOG_Inexlo;
goto clear_trailing0;
}
@@ -429,7 +434,7 @@ gdtoa
#endif
fast_failed:
s = s0;
- dval(d) = d2;
+ dval(&d) = d2;
k = k0;
ilim = ilim0;
}
@@ -441,22 +446,22 @@ gdtoa
ds = tens[k];
if (ndigits < 0 && ilim <= 0) {
S = mhi = 0;
- if (ilim < 0 || dval(d) <= 5*ds)
+ 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;
+ 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) {
+ if (dval(&d) < 0) {
L--;
- dval(d) += ds;
+ dval(&d) += ds;
}
#endif
*s++ = '0' + (int)L;
- if (dval(d) == 0.)
+ if (dval(&d) == 0.)
break;
if (i == ilim) {
if (rdir) {
@@ -465,8 +470,13 @@ gdtoa
inex = STRTOG_Inexlo;
goto ret1;
}
- dval(d) += dval(d);
- if (dval(d) > ds || dval(d) == ds && L & 1) {
+ dval(&d) += dval(&d);
+#ifdef ROUND_BIASED
+ if (dval(&d) >= ds)
+#else
+ if (dval(&d) > ds || (dval(&d) == ds && L & 1))
+#endif
+ {
bump_up:
inex = STRTOG_Inexhi;
while(*--s == '9')
@@ -493,13 +503,15 @@ gdtoa
m5 = b5;
mhi = mlo = 0;
if (leftright) {
- if (mode < 2) {
- i = nbits - bbits;
- if (be - i++ < fpi->emin)
- /* denormal */
- i = be - fpi->emin + 1;
+ i = nbits - bbits;
+ if (be - i++ < fpi->emin && mode != 3 && mode != 5) {
+ /* denormal */
+ i = be - fpi->emin + 1;
+ if (mode >= 2 && ilim > 0 && ilim < i)
+ goto small_ilim;
}
- else {
+ else if (mode >= 2) {
+ small_ilim:
j = ilim - 1;
if (m5 >= j)
m5 -= j;
@@ -560,28 +572,11 @@ gdtoa
* 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)
+ i = ((s5 ? hi0bits(S->x[S->wds-1]) : ULbits - 1) - s2 - 4) & kmask;
+ m2 += i;
+ if ((b2 += i) > 0)
b = lshift(b, b2);
- if (s2 > 0)
+ if ((s2 += i) > 0)
S = lshift(S, s2);
if (k_check) {
if (cmp(b,S) < 0) {
@@ -646,11 +641,11 @@ gdtoa
goto ret;
}
#endif
- if (j < 0 || j == 0 && !mode
+ 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;
@@ -673,7 +668,11 @@ gdtoa
if (j1 > 0) {
b = lshift(b, 1);
j1 = cmp(b, S);
- if ((j1 > 0 || j1 == 0 && dig & 1)
+#ifdef ROUND_BIASED
+ if (j1 >= 0 /*)*/
+#else
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+#endif
&& dig++ == '9')
goto round_9_up;
inex = STRTOG_Inexhi;
@@ -718,13 +717,18 @@ gdtoa
/* Round off last digit */
if (rdir) {
- if (rdir == 2 || b->wds <= 1 && !b->x[0])
+ 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) {
+#ifdef ROUND_BIASED
+ if (j >= 0)
+#else
+ if (j > 0 || (j == 0 && dig & 1))
+#endif
+ {
roundoff:
inex = STRTOG_Inexhi;
while(*--s == '9')
diff --git a/contrib/gdtoa/gdtoa.h b/contrib/gdtoa/gdtoa.h
index e59ebf6..f004ec3 100644
--- a/contrib/gdtoa/gdtoa.h
+++ b/contrib/gdtoa/gdtoa.h
@@ -36,7 +36,7 @@ THIS SOFTWARE.
#include <stddef.h> /* for size_t */
#ifndef Long
-#define Long long
+#define Long int
#endif
#ifndef ULong
typedef unsigned Long ULong;
diff --git a/contrib/gdtoa/gdtoaimp.h b/contrib/gdtoa/gdtoaimp.h
index 9991ffa..75cdc4e 100644
--- a/contrib/gdtoa/gdtoaimp.h
+++ b/contrib/gdtoa/gdtoaimp.h
@@ -96,7 +96,12 @@ THIS SOFTWARE.
* #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 ROUND_BIASED for IEEE-format with biased rounding and arithmetic
+ * that rounds toward +Infinity.
+ * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased
+ * rounding when the underlying floating-point arithmetic uses
+ * unbiased rounding. This prevent using ordinary floating-point
+ * arithmetic when the result could be computed with one rounding error.
* #define Inaccurate_Divide for IEEE-format with correctly rounded
* products but inaccurate quotients, e.g., for Intel i860.
* #define NO_LONG_LONG on machines that do not have a "long long"
@@ -115,7 +120,12 @@ THIS SOFTWARE.
* #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.
+ * directly -- and assumed always to succeed. Similarly, if you
+ * want something other than the system's free() to be called to
+ * recycle memory acquired from MALLOC, #define FREE to be the
+ * name of the alternate routine. (FREE or free is only called in
+ * pathological cases, e.g., in a gdtoa call after a gdtoa return in
+ * mode 3 with thousands of digits requested.)
* #define Omit_Private_Memory to omit logic (added Jan. 1998) for making
* memory allocations from a private pool of memory when possible.
* When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes,
@@ -164,11 +174,6 @@ THIS SOFTWARE.
* #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.
*/
@@ -287,25 +292,14 @@ Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
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]
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
#else
-#define word0(x) ((ULong *)&x)[0]
-#define word1(x) ((ULong *)&x)[1]
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[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 */
+#define dval(x) (x)->d
/* The following definition of Storeinc is appropriate for MIPS processors.
* An alternative that might be better on some machines is
@@ -419,6 +413,11 @@ typedef union { double d; ULong L[2]; } U;
#ifndef IEEE_Arith
#define ROUND_BIASED
+#else
+#ifdef ROUND_BIASED_without_Round_Up
+#undef ROUND_BIASED
+#define ROUND_BIASED
+#endif
#endif
#ifdef RND_PRODQUOT
@@ -659,7 +658,7 @@ extern void memcpy_D2A ANSI((void*, const void*, size_t));
extern int strtorxL ANSI((CONST char *, char **, int, void *));
extern Bigint *sum ANSI((Bigint*, Bigint*));
extern int trailz ANSI((Bigint*));
- extern double ulp ANSI((double));
+ extern double ulp ANSI((U*));
#ifdef __cplusplus
}
diff --git a/contrib/gdtoa/gethex.c b/contrib/gdtoa/gethex.c
index c8ac8ba..a9982c9 100644
--- a/contrib/gdtoa/gethex.c
+++ b/contrib/gdtoa/gethex.c
@@ -57,7 +57,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
static unsigned char *decimalpoint_cache;
if (!(s0 = decimalpoint_cache)) {
s0 = (unsigned char*)localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
@@ -199,7 +199,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
return STRTOG_Normal | STRTOG_Inexlo;
}
n = s1 - s0 - 1;
- for(k = 0; n > (1 << kshift-2) - 1; n >>= 1)
+ for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1)
k++;
b = Balloc(k);
x = b->x;
@@ -314,7 +314,7 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
break;
case FPI_Round_near:
if (lostbits & 2
- && (lostbits & 1) | x[0] & 1)
+ && (lostbits | x[0]) & 1)
up = 1;
break;
case FPI_Round_up:
@@ -333,8 +333,8 @@ gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
irv = STRTOG_Normal;
}
else if (b->wds > k
- || (n = nbits & kmask) !=0
- && hi0bits(x[k-1]) < 32-n) {
+ || ((n = nbits & kmask) !=0
+ && hi0bits(x[k-1]) < 32-n)) {
rshift(b,1);
if (++e > fpi->emax)
goto ovfl;
diff --git a/contrib/gdtoa/hexnan.c b/contrib/gdtoa/hexnan.c
index 58952db..a443721 100644
--- a/contrib/gdtoa/hexnan.c
+++ b/contrib/gdtoa/hexnan.c
@@ -29,10 +29,6 @@ THIS SOFTWARE.
/* Please send bug reports to David M. Gay (dmg at acm dot org,
* with " at " changed at "@" and " dot " changed to "."). */
-/* $FreeBSD$ */
-
-#include <ctype.h>
-
#include "gdtoaimp.h"
static void
@@ -75,14 +71,14 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0)
x1 = xe = x;
havedig = hd0 = i = 0;
s = *sp;
-
- /* FreeBSD local: Accept (but ignore) the '0x' prefix. */
- if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X'))
+ /* allow optional initial 0x or 0X */
+ while((c = *(CONST unsigned char*)(s+1)) && c <= ' ')
+ ++s;
+ if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
+ && *(CONST unsigned char*)(s+3) > ' ')
s += 2;
-
- while(c = *(CONST unsigned char*)++s) {
+ while((c = *(CONST unsigned char*)++s)) {
if (!(h = hexdig[c])) {
-#if 0
if (c <= ' ') {
if (hd0 < havedig) {
if (x < x1 && i < 8)
@@ -96,14 +92,26 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0)
x1 = x;
i = 0;
}
+ while(*(CONST unsigned char*)(s+1) <= ' ')
+ ++s;
+ if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')
+ && *(CONST unsigned char*)(s+3) > ' ')
+ s += 2;
continue;
}
if (/*(*/ c == ')' && havedig) {
*sp = s + 1;
break;
}
+#ifndef GDTOA_NON_PEDANTIC_NANCHECK
+ do {
+ if (/*(*/ c == ')') {
+ *sp = s + 1;
+ break;
+ }
+ } while((c = *++s));
#endif
- break;
+ return STRTOG_NaN;
}
havedig++;
if (++i > 8) {
@@ -112,9 +120,11 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0)
i = 1;
*--x = 0;
}
- *x = (*x << 4) | h & 0xf;
+ *x = (*x << 4) | (h & 0xf);
}
- if (havedig && x < x1 && i < 8)
+ if (!havedig)
+ return STRTOG_NaN;
+ if (x < x1 && i < 8)
L_shift(x, x1, i);
if (x > x0) {
x1 = x0;
@@ -128,7 +138,6 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0)
if ( (i = nbits & (ULbits-1)) !=0)
*xe &= ((ULong)0xffffffff) >> (ULbits - i);
}
- if (havedig) {
for(x1 = xe;; --x1) {
if (*x1 != 0)
break;
@@ -137,22 +146,5 @@ hexnan( CONST char **sp, FPI *fpi, ULong *x0)
break;
}
}
- }
-
- /*
- * FreeBSD local: Accept all the sequences allowed by C99 and update
- * the tail pointer correctly. Don't accept any invalid sequences.
- */
- if (c == '\0') /* nan() calls this, too; tolerate a missing ')' */
- return STRTOG_NaNbits;
- if (c != ')') {
- while(c = *(CONST unsigned char*)++s) {
- if (c == ')')
- break;
- if (!isalnum(c) && c != '_')
- return STRTOG_NaNbits;
- }
- }
- *sp = s + 1;
return STRTOG_NaNbits;
}
diff --git a/contrib/gdtoa/makefile b/contrib/gdtoa/makefile
index 367eb9c..b1f18cd 100644
--- a/contrib/gdtoa/makefile
+++ b/contrib/gdtoa/makefile
@@ -30,6 +30,8 @@ CFLAGS = -g
.c.o:
$(CC) -c $(CFLAGS) $*.c
+# invoke "make Printf" to add printf.o to gdtoa.a (if desired)
+
all: arith.h gd_qnan.h gdtoa.a
arith.h: arithchk.c
@@ -42,27 +44,36 @@ gd_qnan.h: arith.h qnan.c
./a.out >gd_qnan.h
rm -f a.out qnan.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
+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
+Printf: all printf.c
+ $(CC) -c $(CFLAGS) printf.c
+ ar ruv gdtoa.a printf.o
+ rm printf.o
+ touch Printf
+
# 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 gdtoa_fltrnds.h gdtoaimp.h\
- gethex.c gmisc.c hd_init.c hexnan.c makefile misc.c qnan.c smisc.c\
- strtoIQ.c strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c strtoIxL.c\
- strtod.c strtodI.c strtodg.c strtodnrp.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
+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\
+ gdtoa_fltrnds.h gdtoaimp.h gethex.c gmisc.c hd_init.c hexnan.c\
+ makefile misc.c printf.c printf.c0 qnan.c smisc.c stdio1.h\
+ strtoIQ.c strtoId.c strtoIdd.c strtoIf.c strtoIg.c strtoIx.c\
+ strtoIxL.c strtod.c strtodI.c strtodg.c strtodnrp.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
+# "make -r 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
@@ -71,4 +82,4 @@ xsum.out: xsum0.out $(xs0)
cmp xsum0.out xsum1.out && mv xsum1.out xsum.out || diff xsum[01].out
clean:
- rm -f arith.h gd_qnan.h *.[ao] xsum.out xsum1.out
+ rm -f arith.h gd_qnan.h *.[ao] Printf xsum.out xsum1.out
diff --git a/contrib/gdtoa/misc.c b/contrib/gdtoa/misc.c
index 8d2888e..e5f7b04 100644
--- a/contrib/gdtoa/misc.c
+++ b/contrib/gdtoa/misc.c
@@ -92,7 +92,11 @@ Bfree
{
if (v) {
if (v->k > Kmax)
+#ifdef FREE
+ FREE((void*)v);
+#else
free((void*)v);
+#endif
else {
ACQUIRE_DTOA_LOCK(0);
v->next = freelist[v->k];
@@ -110,8 +114,8 @@ lo0bits
(ULong *y)
#endif
{
- register int k;
- register ULong x = *y;
+ int k;
+ ULong x = *y;
if (x & 7) {
if (x & 1)
@@ -210,12 +214,12 @@ multadd
int
hi0bits_D2A
#ifdef KR_headers
- (x) register ULong x;
+ (x) ULong x;
#else
- (register ULong x)
+ (ULong x)
#endif
{
- register int k = 0;
+ int k = 0;
if (!(x & 0xffff0000)) {
k = 16;
@@ -618,12 +622,12 @@ b2d
{
ULong *xa, *xa0, w, y, z;
int k;
- double d;
+ U d;
#ifdef VAX
ULong d0, d1;
#else
-#define d0 word0(d)
-#define d1 word1(d)
+#define d0 word0(&d)
+#define d1 word1(&d)
#endif
xa0 = a->x;
@@ -636,16 +640,16 @@ b2d
*e = 32 - k;
#ifdef Pack_32
if (k < Ebits) {
- d0 = Exp_1 | y >> Ebits - k;
+ d0 = Exp_1 | y >> (Ebits - k);
w = xa > xa0 ? *--xa : 0;
- d1 = y << (32-Ebits) + k | w >> Ebits - k;
+ 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;
+ d0 = Exp_1 | y << k | z >> (32 - k);
y = xa > xa0 ? *--xa : 0;
- d1 = z << k | y >> 32 - k;
+ d1 = z << k | y >> (32 - k);
}
else {
d0 = Exp_1 | y;
@@ -669,10 +673,10 @@ b2d
#endif
ret_d:
#ifdef VAX
- word0(d) = d0 >> 16 | d0 << 16;
- word1(d) = d1 >> 16 | d1 << 16;
+ word0(&d) = d0 >> 16 | d0 << 16;
+ word1(&d) = d1 >> 16 | d1 << 16;
#endif
- return dval(d);
+ return dval(&d);
}
#undef d0
#undef d1
@@ -680,12 +684,13 @@ b2d
Bigint *
d2b
#ifdef KR_headers
- (d, e, bits) double d; int *e, *bits;
+ (dd, e, bits) double dd; int *e, *bits;
#else
- (double d, int *e, int *bits)
+ (double dd, int *e, int *bits)
#endif
{
Bigint *b;
+ U d;
#ifndef Sudden_Underflow
int i;
#endif
@@ -693,11 +698,14 @@ d2b
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)
+#define d0 word0(&d)
+#define d1 word1(&d)
+#endif
+ d.d = dd;
+#ifdef VAX
+ d0 = word0(&d) >> 16 | word0(&d) << 16;
+ d1 = word1(&d) >> 16 | word1(&d) << 16;
#endif
#ifdef Pack_32
@@ -721,7 +729,7 @@ d2b
#ifdef Pack_32
if ( (y = d1) !=0) {
if ( (k = lo0bits(&y)) !=0) {
- x[0] = y | z << 32 - k;
+ x[0] = y | z << (32 - k);
z >>= k;
}
else
@@ -732,10 +740,6 @@ d2b
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;
#ifndef Sudden_Underflow
@@ -794,7 +798,7 @@ d2b
#endif
#ifdef IBM
*e = (de - Bias - (P-1) << 2) + k;
- *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
+ *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask);
#else
*e = de - Bias - (P-1) + k;
*bits = P - k;
@@ -847,7 +851,7 @@ strcp_D2A(a, b) char *a; char *b;
strcp_D2A(char *a, CONST char *b)
#endif
{
- while(*a = *b++)
+ while((*a = *b++))
a++;
return a;
}
@@ -861,8 +865,8 @@ memcpy_D2A(a, b, len) Char *a; Char *b; size_t len;
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;
+ char *a = (char*)a1, *ae = a + len;
+ char *b = (char*)b1, *a0 = a;
while(a < ae)
*a++ = *b++;
return a0;
diff --git a/contrib/gdtoa/printf.c b/contrib/gdtoa/printf.c
new file mode 100644
index 0000000..02f1f3c
--- /dev/null
+++ b/contrib/gdtoa/printf.c
@@ -0,0 +1,8 @@
+#ifdef __sun
+#define Use_GDTOA_Qtype
+#else
+#if defined(__i386) || defined(__x86_64)
+#define Use_GDTOA_for_i386_long_double
+#endif
+#endif
+#include "printf.c0"
diff --git a/contrib/gdtoa/printf.c0 b/contrib/gdtoa/printf.c0
new file mode 100644
index 0000000..c33bcc1
--- /dev/null
+++ b/contrib/gdtoa/printf.c0
@@ -0,0 +1,1669 @@
+/****************************************************************
+Copyright (C) 1997, 1999, 2001 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 implements most of ANSI C's printf, fprintf, and sprintf,
+ * omitting L, with %.0g and %.0G giving the shortest decimal string
+ * that rounds to the number being converted, and with negative
+ * precisions allowed for %f.
+ */
+
+#ifdef KR_headers
+#include "varargs.h"
+#else
+#include "stddef.h"
+#include "stdarg.h"
+#include "stdlib.h"
+#endif
+
+#ifdef Use_GDTOA_for_i386_long_double /*{{*/
+#include "gdtoa.h"
+#else /*}{*/
+#ifndef NO_PRINTF_A_FMT /*{*/
+#include "gdtoa.h"
+#endif /*}*/
+#endif /*}}*/
+
+#ifdef __i386
+#define NO_GDTOA_i386_Quad
+#endif
+
+#ifdef Use_GDTOA_for_i386_long_double /*{*/
+#ifndef NO_GDTOA_i386_Quad /*{*/
+#define GDTOA_both
+#define Use_GDTOA_Qtype
+#ifdef __ICC__ /* or __INTEL_COMPILER__ or __INTEL_COMPILER ?? */
+#define GDTOA_Qtype _Quad
+#else
+#define GDTOA_Qtype __float128
+#endif
+#endif /*} NO_GDTOA_i386_Quad */
+#endif /*} Use_GDTOA_for_i386_long_double */
+
+#ifdef Use_GDTOA_Qtype /*{*/
+#ifndef GDTOA_H_INCLUDED
+#include "gdtoa.h"
+#endif
+#ifndef GDTOA_Qtype
+#define GDTOA_Qtype long double
+#endif
+#endif /*}*/
+
+#ifndef GDTOA_H_INCLUDED /*{*/
+
+ 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};
+
+ 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
+ };
+#endif /*}*/
+
+#ifdef NO_PRINTF_A_FMT /*{{*/
+#define WANT_A_FMT(x) /*nothing*/
+#else /*}{*/
+#define WANT_A_FMT(x) x
+#endif /*}}*/
+
+#include "stdio1.h"
+#include "string.h"
+#include "errno.h"
+
+ typedef struct
+Finfo {
+ union { FILE *cf; char *sf; } u;
+ char *ob0, *obe1;
+ size_t lastlen;
+ } Finfo;
+
+ typedef char *(*pgdtoa) ANSI((FPI*, int be, ULong *bits, int *kind, int mode, int ndigits, int *decpt, char **rve));
+
+ typedef struct
+FPBits {
+ ULong bits[4]; /* sufficient for quad; modify if considering wider types */
+ FPI *fpi;
+ pgdtoa gdtoa;
+ int sign;
+ int ex; /* exponent */
+ int kind;
+ } FPBits;
+
+ typedef union U
+{
+ double d;
+ long double ld;
+#ifdef GDTOA_Qtype
+ GDTOA_Qtype Qd;
+#endif
+ unsigned int ui[4];
+ unsigned short us[5];
+ } U;
+
+ typedef char *(*Putfunc) ANSI((Finfo*, int*));
+ typedef void (*Fpbits) ANSI((U*, FPBits*));
+
+/* Would have preferred typedef void (*Fpbits)(va_list*, FPBits*)
+ * but gcc is buggy in this regard.
+ */
+
+#ifdef Use_GDTOA_for_i386_long_double /*{*/
+
+#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
+
+ static void
+xfpbits(U *u, FPBits *b)
+{
+ ULong *bits;
+ int ex, i;
+ static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
+
+ b->fpi = &fpi0;
+ b->gdtoa = gdtoa;
+ b->sign = u->us[_0] & 0x8000;
+ bits = b->bits;
+ bits[1] = (u->us[_1] << 16) | u->us[_2];
+ bits[0] = (u->us[_3] << 16) | u->us[_4];
+ if ( (ex = u->us[_0] & 0x7fff) !=0) {
+ i = STRTOG_Normal;
+ if (ex == 0x7fff)
+ /* Infinity or NaN */
+ i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
+ }
+ else if (bits[0] | bits[1]) {
+ i = STRTOG_Denormal;
+ ex = 1;
+ }
+ else
+ i = STRTOG_Zero;
+ b->kind = i;
+ b->ex = ex - (0x3fff + 63);
+ }
+
+#undef _0
+#undef _1
+#undef _2
+#undef _3
+#undef _4
+#define GDTOA_LD_fpbits xfpbits
+#endif /*} Use_GDTOA_for_i386_long_double */
+
+#ifdef Use_GDTOA_Qtype /*{*/
+#include "gdtoa.h"
+#ifndef GDTOA_Qtype
+#define GDTOA_Qtype long double
+#endif
+#ifdef GDTOA_LD_fpbits
+#define GDTOA_Q_fpbits Qfpbits
+#else
+#define GDTOA_LD_fpbits Qfpbits
+#endif
+
+#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
+
+ static void
+Qfpbits(U *u, FPBits *b)
+{
+ ULong *bits;
+ int ex, i;
+ static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
+
+ b->fpi = &fpi0;
+ b->gdtoa = gdtoa;
+ b->sign = u->ui[_0] & 0x80000000L;
+ bits = b->bits;
+ bits[3] = u->ui[_0] & 0xffff;
+ bits[2] = u->ui[_1];
+ bits[1] = u->ui[_2];
+ bits[0] = u->ui[_3];
+ if ( (ex = (u->ui[_0] & 0x7fff0000L) >> 16) !=0) {
+ if (ex == 0x7fff) {
+ /* Infinity or NaN */
+ i = bits[0] | bits[1] | bits[2] | bits[3]
+ ? STRTOG_NaN : STRTOG_Infinite;
+ }
+ else {
+ i = STRTOG_Normal;
+ bits[3] |= 0x10000;
+ }
+ }
+ else if (bits[0] | bits[1] | bits[2] | bits[3]) {
+ i = STRTOG_Denormal;
+ ex = 1;
+ }
+ else
+ i = STRTOG_Zero;
+ b->kind = i;
+ b->ex = ex - (0x3fff + 112);
+ }
+
+#undef _0
+#undef _1
+#undef _2
+#undef _3
+#endif /*} GDTOA_Qtype */
+
+#ifdef KR_headers
+#define Const /* const */
+#define Voidptr char*
+#ifndef size_t__
+#define size_t int
+#define size_t__
+#endif
+
+#else
+
+#define Const const
+#define Voidptr void*
+
+#endif
+
+#undef MESS
+#ifndef Stderr
+#define Stderr stderr
+#endif
+
+#ifdef _windows_
+#undef PF_BUF
+#define MESS
+#include "mux0.h"
+#define stdout_or_err(f) (f == stdout)
+#else
+#define stdout_or_err(f) (f == Stderr || f == stdout)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ extern char *dtoa ANSI((double, int, int, int*, int*, char **));
+ extern void freedtoa ANSI((char*));
+
+
+
+#ifdef USE_ULDIV
+/* This is for avoiding 64-bit divisions on the DEC Alpha, since */
+/* they are not portable among variants of OSF1 (DEC's Unix). */
+
+#define ULDIV(a,b) uldiv_ASL(a,(unsigned long)(b))
+
+#ifndef LLBITS
+#define LLBITS 6
+#endif
+#ifndef ULONG
+#define ULONG unsigned long
+#endif
+
+ static int
+klog(ULONG x)
+{
+ int k, rv = 0;
+
+ if (x > 1L)
+ for(k = 1 << LLBITS-1;;) {
+ if (x >= (1L << k)) {
+ rv |= k;
+ x >>= k;
+ }
+ if (!(k >>= 1))
+ break;
+ }
+ return rv;
+ }
+
+ ULONG
+uldiv_ASL(ULONG a, ULONG b)
+{
+ int ka;
+ ULONG c, k;
+ static ULONG b0;
+ static int kb;
+
+ if (a < b)
+ return 0;
+ if (b != b0) {
+ b0 = b;
+ kb = klog(b);
+ }
+ k = 1;
+ if ((ka = klog(a) - kb) > 0) {
+ k <<= ka;
+ b <<= ka;
+ }
+ c = 0;
+ for(;;) {
+ if (a >= b) {
+ a -= b;
+ c |= k;
+ }
+ if (!(k >>= 1))
+ break;
+ a <<= 1;
+ }
+ return c;
+ }
+
+#else
+#define ULDIV(a,b) a / b
+#endif /* USE_ULDIV */
+
+#ifdef PF_BUF
+FILE *stderr_ASL = (FILE*)&stderr_ASL;
+void (*pfbuf_print_ASL) ANSI((char*));
+char *pfbuf_ASL;
+static char *pfbuf_next;
+static size_t pfbuf_len;
+extern Char *mymalloc_ASL ANSI((size_t));
+extern Char *myralloc_ASL ANSI((void *, size_t));
+
+#undef fflush
+#ifdef old_fflush_ASL
+#define fflush old_fflush_ASL
+#endif
+
+ void
+fflush_ASL(FILE *f)
+{
+ if (f == stderr_ASL) {
+ if (pfbuf_ASL && pfbuf_print_ASL) {
+ (*pfbuf_print_ASL)(pfbuf_ASL);
+ free(pfbuf_ASL);
+ pfbuf_ASL = 0;
+ }
+ }
+ else
+ fflush(f);
+ }
+
+ static void
+pf_put(char *buf, int len)
+{
+ size_t x, y;
+ if (!pfbuf_ASL) {
+ x = len + 256;
+ if (x < 512)
+ x = 512;
+ pfbuf_ASL = pfbuf_next = (char*)mymalloc_ASL(pfbuf_len = x);
+ }
+ else if ((y = (pfbuf_next - pfbuf_ASL) + len) >= pfbuf_len) {
+ x = pfbuf_len;
+ while((x <<= 1) <= y);
+ y = pfbuf_next - pfbuf_ASL;
+ pfbuf_ASL = (char*)myralloc_ASL(pfbuf_ASL, x);
+ pfbuf_next = pfbuf_ASL + y;
+ pfbuf_len = x;
+ }
+ memcpy(pfbuf_next, buf, len);
+ pfbuf_next += len;
+ *pfbuf_next = 0;
+ }
+
+ static char *
+pfput(Finfo *f, int *rvp)
+{
+ int n;
+ char *ob0 = f->ob0;
+ *rvp += n = (int)(f->obe1 - ob0);
+ pf_put(ob0, n);
+ return ob0;
+ }
+#endif /* PF_BUF */
+
+ static char *
+Fput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ char *ob0 = f->ob0;
+
+ *rvp += f->obe1 - ob0;
+ *f->obe1 = 0;
+ fputs(ob0, f->u.cf);
+ return ob0;
+ }
+
+
+#ifdef _windows_
+int stdout_fileno_ASL = 1;
+
+ static char *
+Wput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ char *ob0 = f->ob0;
+
+ *rvp += f->obe1 - ob0;
+ *f->obe1 = 0;
+ mwrite(ob0, f->obe1 - ob0);
+ return ob0;
+ }
+#endif /*_windows_*/
+
+
+#ifdef IEEE_MC68k
+#define _0 0
+#define _1 1
+#endif
+#ifdef IEEE_8087
+#define _0 1
+#define _1 0
+#endif
+
+ static void
+dfpbits(U *u, FPBits *b)
+{
+ ULong *bits;
+ int ex, i;
+ static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 };
+
+ b->fpi = &fpi0;
+ b->gdtoa = gdtoa;
+ b->sign = u->ui[_0] & 0x80000000L;
+ bits = b->bits;
+ bits[1] = u->ui[_0] & 0xfffff;
+ bits[0] = u->ui[_1];
+ if ( (ex = (u->ui[_0] & 0x7ff00000L) >> 20) !=0) {
+ if (ex == 0x7ff) {
+ /* Infinity or NaN */
+ i = bits[0] | bits[1] ? STRTOG_NaN : STRTOG_Infinite;
+ }
+ else {
+ i = STRTOG_Normal;
+ bits[1] |= 0x100000;
+ }
+ }
+ else if (bits[0] | bits[1]) {
+ i = STRTOG_Denormal;
+ ex = 1;
+ }
+ else
+ i = STRTOG_Zero;
+ b->kind = i;
+ b->ex = ex - (0x3ff + 52);
+ }
+
+#undef _0
+#undef _1
+
+#ifdef Honor_FLT_ROUNDS /*{{*/
+#ifdef Trust_FLT_ROUNDS /*{{*/
+#define RoundCheck if (Rounding == -1) Rounding = Flt_Rounds; if (Rounding != 1){\
+ fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
+#else /*}{*/
+#define RoundCheck if (Rounding == -1) { Rounding = 1; switch((fegetround()) {\
+ case FE_TOWARDZERO: Rounding = 0; break;\
+ case FE_UPWARD: Rounding = 2; break;\
+ case FE_DOWNWARD: Rounding = 3; }}\
+ if (Rounding != 1){\
+ fpi1 = *fpb.fpi; fpi1.rounding = Rounding; fpb.fpi = &fpi1;}
+#endif /*}}*/
+#else /*}{*/
+#define RoundCheck /*nothing*/
+#endif /*}}*/
+
+#ifndef NO_PRINTF_A_FMT /*{*/
+ static int
+fpiprec(FPBits *b) /* return number of hex digits minus 1, or 0 for zero */
+{
+ FPI *fpi;
+ ULong *bits;
+ int i, j, k, m;
+
+ if (b->kind == STRTOG_Zero)
+ return b->ex = 0;
+ fpi = b->fpi;
+ bits = b->bits;
+ for(k = (fpi->nbits - 1) >> 2; k > 0; --k)
+ if ((bits[k >> 3] >> 4*(k & 7)) & 0xf) {
+ m = k >> 3;
+ for(i = 0; i <= m; ++i)
+ if (bits[i]) {
+ if (i > 0) {
+ k -= 8*i;
+ b->ex += 32*i;
+ for(j = i; j <= m; ++j)
+ bits[j-i] = bits[j];
+ }
+ break;
+ }
+ for(i = 0; i < 28 && !((bits[0] >> i) & 0xf); i += 4);
+ if (i) {
+ b->ex += i;
+ m = k >> 3;
+ k -= (i >> 2);
+ for(j = 0;;++j) {
+ bits[j] >>= i;
+ if (j == m)
+ break;
+ bits[j] |= bits[j+1] << (32 - i);
+ }
+ }
+ break;
+ }
+ return k;
+ }
+
+ static int
+bround(FPBits *b, int prec, int prec1) /* round to prec hex digits after the "." */
+{ /* prec1 = incoming precision (after ".") */
+ FPI *fpi = b->fpi;
+ ULong *bits, t;
+ int i, inc, j, k, m, n;
+#ifdef Honor_FLT_ROUNDS
+ int rounding = fpi->rounding;
+
+ if (rounding > FPI_Round_near && b->sign)
+ rounding = FPI_Round_up + FPI_Round_down - rounding;
+ if (rounding == FPI_Round_down)
+ rounding = FPI_Round_zero;
+#endif
+ m = prec1 - prec;
+ bits = b->bits;
+ inc = 0;
+#ifdef Honor_FLT_ROUNDS
+ switch(rounding) {
+ case FPI_Round_up:
+ for(i = 0; i < m; i += 8)
+ if (bits[i>>3])
+ goto inc1;
+ if ((j = i - m) > 0 && bits[(i-8)>>3] << j*4)
+ goto inc1;
+ break;
+ case FPI_Round_near:
+#endif
+ k = m - 1;
+ if ((t = bits[k >> 3] >> (j = (k&7)*4)) & 8) {
+ if (t & 7)
+ goto inc1;
+ if (j && bits[k >> 3] << (32 - j))
+ goto inc1;
+ while(k >= 8) {
+ k -= 8;
+ if (bits[k>>3]) {
+ inc1:
+ inc = 1;
+ goto haveinc;
+ }
+ }
+ }
+#ifdef Honor_FLT_ROUNDS
+ }
+#endif
+ haveinc:
+ b->ex += m*4;
+ i = m >> 3;
+ k = prec1 >> 3;
+ j = i;
+ if ((n = 4*(m & 7)))
+ for(;; ++j) {
+ bits[j-i] = bits[j] >> n;
+ if (j == k)
+ break;
+ bits[j-i] |= bits[j+1] << (32-n);
+ }
+ else
+ for(;; ++j) {
+ bits[j-i] = bits[j];
+ if (j == k)
+ break;
+ }
+ k = prec >> 3;
+ if (inc) {
+ for(j = 0; !(++bits[j] & 0xffffffff); ++j);
+ if (j > k) {
+ onebit:
+ bits[0] = 1;
+ b->ex += 4*prec;
+ return 1;
+ }
+ if ((j = prec & 7) < 7 && bits[k] >> (j+1)*4)
+ goto onebit;
+ }
+ for(i = 0; !(bits[i >> 3] & (0xf << 4*(i&7))); ++i);
+ if (i) {
+ b->ex += 4*i;
+ prec -= i;
+ j = i >> 3;
+ i &= 7;
+ i *= 4;
+ for(m = j; ; ++m) {
+ bits[m-j] = bits[m] >> i;
+ if (m == k)
+ break;
+ bits[m-j] |= bits[m+1] << (32 - i);
+ }
+ }
+ return prec;
+ }
+#endif /*}NO_PRINTF_A_FMT*/
+
+#define put(x) { *outbuf++ = x; if (outbuf == obe) outbuf = (*fput)(f,&rv); }
+
+ static int
+x_sprintf
+#ifdef KR_headers
+ (obe, fput, f, fmt, ap)
+ char *obe, *fmt; Finfo *f; Putfunc fput; va_list ap;
+#else
+ (char *obe, Putfunc fput, Finfo *f, const char *fmt, va_list ap)
+#endif
+{
+ FPBits fpb;
+ Fpbits fpbits;
+ U u;
+ char *digits, *ob0, *outbuf, *s, *s0, *se;
+ Const char *fmt0;
+ char buf[32];
+ long i;
+ unsigned long j, ul;
+ double x;
+ int alt, base, c, decpt, dot, conv, i1, k, lead0, left,
+ len, prec, prec1, psign, rv, sign, width;
+ long Ltmp, *ip;
+ short sh;
+ unsigned short us;
+ unsigned int ui;
+#ifdef Honor_FLT_ROUNDS
+ FPI fpi1;
+ int Rounding = -1;
+#endif
+#ifndef NO_PRINTF_A_FMT /*{*/
+ int bex, bw;
+#endif /*} NO_PRINTF_A_FMT */
+ static char hex[] = "0123456789abcdefpx";
+ static char Hex[] = "0123456789ABCDEFPX";
+
+ ob0 = outbuf = f->ob0;
+ rv = 0;
+ for(;;) {
+ for(;;) {
+ switch(c = *fmt++) {
+ case 0:
+ goto done;
+ case '%':
+ break;
+ default:
+ put(c)
+ continue;
+ }
+ break;
+ }
+ alt=dot=lead0=left=len=prec=psign=sign=width=0;
+ fpbits = dfpbits;
+ fmt0 = fmt;
+ fmtloop:
+ switch(conv = *fmt++) {
+ case ' ':
+ case '+':
+ sign = conv;
+ goto fmtloop;
+ case '-':
+ if (dot)
+ psign = 1;
+ else
+ left = 1;
+ goto fmtloop;
+ case '#':
+ alt = 1;
+ goto fmtloop;
+ case '0':
+ if (!lead0 && !dot) {
+ lead0 = 1;
+ goto fmtloop;
+ }
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ k = conv - '0';
+ while((c = *fmt) >= '0' && c <= '9') {
+ k = 10*k + c - '0';
+ fmt++;
+ }
+ if (dot)
+ prec = psign ? -k : k;
+ else
+ width = k;
+ goto fmtloop;
+ case 'h':
+ len = 2;
+ goto fmtloop;
+ case 'L':
+#ifdef GDTOA_LD_fpbits /*{*/
+ fpbits = GDTOA_LD_fpbits;
+#ifdef GDTOA_Q_fpbits
+ if (*fmt == 'q') {
+ ++fmt;
+ fpbits = Qfpbits;
+ }
+#endif
+#endif /*}*/
+ goto fmtloop;
+ case 'l':
+ len = 1;
+ goto fmtloop;
+ case '.':
+ dot = 1;
+ goto fmtloop;
+ case '*':
+ k = va_arg(ap, int);
+ if (dot)
+ prec = k;
+ else {
+ if (k < 0) {
+ sign = '-';
+ k = -k;
+ }
+ width = k;
+ }
+ goto fmtloop;
+ case 'c':
+ c = va_arg(ap, int);
+ put(c)
+ continue;
+ case '%':
+ put(conv)
+ continue;
+ case 'u':
+ switch(len) {
+ case 0:
+ ui = va_arg(ap, int);
+ i = ui;
+ break;
+ case 1:
+ i = va_arg(ap, long);
+ break;
+ case 2:
+ us = va_arg(ap, int);
+ i = us;
+ }
+ sign = 0;
+ goto have_i;
+ case 'i':
+ case 'd':
+ switch(len) {
+ case 0:
+ k = va_arg(ap, int);
+ i = k;
+ break;
+ case 1:
+ i = va_arg(ap, long);
+ break;
+ case 2:
+ sh = va_arg(ap, int);
+ i = sh;
+ }
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+ have_i:
+ base = 10;
+ ul = i;
+ digits = hex;
+ baseloop:
+ if (dot)
+ lead0 = 0;
+ s = buf;
+ if (!ul)
+ alt = 0;
+ do {
+ j = ULDIV(ul, base);
+ *s++ = digits[ul - base*j];
+ }
+ while((ul = j));
+ prec -= c = s - buf;
+ if (alt && conv == 'o' && prec <= 0)
+ prec = 1;
+ if ((width -= c) > 0) {
+ if (prec > 0)
+ width -= prec;
+ if (sign)
+ width--;
+ if (alt == 2)
+ width--;
+ }
+ if (left) {
+ if (alt == 2)
+ put('0') /* for 0x */
+ if (sign)
+ put(sign)
+ while(--prec >= 0)
+ put('0')
+ do put(*--s)
+ while(s > buf);
+ while(--width >= 0)
+ put(' ')
+ continue;
+ }
+ if (width > 0) {
+ if (lead0) {
+ if (alt == 2)
+ put('0')
+ if (sign)
+ put(sign)
+ while(--width >= 0)
+ put('0')
+ goto s_loop;
+ }
+ else
+ while(--width >= 0)
+ put(' ')
+ }
+ if (alt == 2)
+ put('0')
+ if (sign)
+ put(sign)
+ s_loop:
+ while(--prec >= 0)
+ put('0')
+ do put(*--s)
+ while(s > buf);
+ continue;
+ case 'n':
+ ip = va_arg(ap, long*);
+ if (!ip)
+ ip = &Ltmp;
+ c = outbuf - ob0 + rv;
+ switch(len) {
+ case 0:
+ *(int*)ip = c;
+ break;
+ case 1:
+ *ip = c;
+ break;
+ case 2:
+ *(short*)ip = c;
+ }
+ break;
+ case 'p':
+ len = alt = 1;
+ /* no break */
+ case 'x':
+ digits = hex;
+ goto more_x;
+ case 'X':
+ digits = Hex;
+ more_x:
+ if (alt) {
+ alt = 2;
+ sign = conv;
+ }
+ else
+ sign = 0;
+ base = 16;
+ get_u:
+ switch(len) {
+ case 0:
+ ui = va_arg(ap, int);
+ ul = ui;
+ break;
+ case 1:
+ ul = va_arg(ap, long);
+ break;
+ case 2:
+ us = va_arg(ap, int);
+ ul = us;
+ }
+ if (!ul)
+ sign = alt = 0;
+ goto baseloop;
+ case 'o':
+ base = 8;
+ digits = hex;
+ goto get_u;
+ case 's':
+ s0 = 0;
+ s = va_arg(ap, char*);
+ if (!s)
+ s = "<NULL>";
+ if (prec < 0)
+ prec = 0;
+ have_s:
+ if (dot) {
+ for(c = 0; c < prec; c++)
+ if (!s[c])
+ break;
+ prec = c;
+ }
+ else
+ prec = strlen(s);
+ width -= prec;
+ if (!left)
+ while(--width >= 0)
+ put(' ')
+ while(--prec >= 0)
+ put(*s++)
+ while(--width >= 0)
+ put(' ')
+ if (s0)
+ freedtoa(s0);
+ continue;
+ case 'f':
+ if (!dot)
+ prec = 6;
+#ifdef GDTOA_H_INCLUDED
+ if (fpbits == dfpbits) {
+#endif
+ x = va_arg(ap, double);
+ s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
+#ifdef GDTOA_H_INCLUDED
+ }
+ else {
+#ifdef GDTOA_both
+ if (fpbits == GDTOA_LD_fpbits)
+ u.ld = va_arg(ap, long double);
+ else
+ u.Qd = va_arg(ap, GDTOA_Qtype);
+#else
+ u.ld = va_arg(ap, long double);
+#endif
+ fpbits(&u, &fpb);
+ RoundCheck
+ s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
+ &fpb.kind, 3, prec, &decpt, &se);
+ }
+#endif
+ if (decpt == 9999) {
+ fmt9999:
+ dot = prec = alt = 0;
+ if (*s == 'N')
+ goto have_s;
+ decpt = strlen(s);
+ }
+ f_fmt:
+ if (fpb.sign && (x||sign))
+ sign = '-';
+ if (prec > 0)
+ width -= prec;
+ if (width > 0) {
+ if (sign)
+ --width;
+ if (decpt <= 0) {
+ --width;
+ if (prec > 0)
+ --width;
+ }
+ else {
+ if (s == se)
+ decpt = 1;
+ width -= decpt;
+ if (prec > 0 || alt)
+ --width;
+ }
+ }
+ if (width > 0 && !left) {
+ if (lead0) {
+ if (sign)
+ put(sign)
+ sign = 0;
+ do put('0')
+ while(--width > 0);
+ }
+ else do put(' ')
+ while(--width > 0);
+ }
+ if (sign)
+ put(sign)
+ if (decpt <= 0) {
+ put('0')
+ if (prec > 0 || alt)
+ put('.')
+ while(decpt < 0) {
+ put('0')
+ prec--;
+ decpt++;
+ }
+ }
+ else {
+ do {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ while(--decpt > 0);
+ if (prec > 0 || alt)
+ put('.')
+ }
+ while(--prec >= 0) {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ while(--width >= 0)
+ put(' ')
+ if (s0)
+ freedtoa(s0);
+ continue;
+ case 'G':
+ case 'g':
+ if (!dot)
+ prec = 6;
+ if (prec < 0)
+ prec = 0;
+#ifdef GDTOA_H_INCLUDED
+ if (fpbits == dfpbits) {
+#endif
+ x = va_arg(ap, double);
+ s = s0 = dtoa(x, prec ? 2 : 0, prec, &decpt,
+ &fpb.sign, &se);
+#ifdef GDTOA_H_INCLUDED
+ }
+ else {
+#ifdef GDTOA_both
+ if (fpbits == GDTOA_LD_fpbits)
+ u.ld = va_arg(ap, long double);
+ else
+ u.Qd = va_arg(ap, GDTOA_Qtype);
+#else
+ u.ld = va_arg(ap, long double);
+#endif
+ fpbits(&u, &fpb);
+ RoundCheck
+ s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
+ &fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
+ }
+#endif
+ if (decpt == 9999)
+ goto fmt9999;
+ c = se - s;
+ prec1 = prec;
+ if (!prec) {
+ prec = c;
+ prec1 = c + (s[1] || alt ? 5 : 4);
+ /* %.0g gives 10 rather than 1e1 */
+ }
+ if (decpt > -4 && decpt <= prec1) {
+ if (alt)
+ prec -= decpt;
+ else
+ prec = c - decpt;
+ if (prec < 0)
+ prec = 0;
+ goto f_fmt;
+ }
+ conv -= 2;
+ if (!alt && prec > c)
+ prec = c;
+ --prec;
+ goto e_fmt;
+ case 'e':
+ case 'E':
+ if (!dot)
+ prec = 6;
+ if (prec < 0)
+ prec = 0;
+#ifdef GDTOA_H_INCLUDED
+ if (fpbits == dfpbits) {
+#endif
+ x = va_arg(ap, double);
+ s = s0 = dtoa(x, prec ? 2 : 0, prec+1, &decpt,
+ &fpb.sign, &se);
+#ifdef GDTOA_H_INCLUDED
+ }
+ else {
+#ifdef GDTOA_both
+ if (fpbits == GDTOA_LD_fpbits)
+ u.ld = va_arg(ap, long double);
+ else
+ u.Qd = va_arg(ap, GDTOA_Qtype);
+#else
+ u.ld = va_arg(ap, long double);
+#endif
+ fpbits(&u, &fpb);
+ RoundCheck
+ s = s0 = fpb.gdtoa(fpb.fpi, fpb.ex, fpb.bits,
+ &fpb.kind, prec ? 2 : 0, prec, &decpt, &se);
+ }
+#endif
+ if (decpt == 9999)
+ goto fmt9999;
+ e_fmt:
+ if (fpb.sign && (x||sign))
+ sign = '-';
+ if ((width -= prec + 5) > 0) {
+ if (sign)
+ --width;
+ if (prec || alt)
+ --width;
+ }
+ if ((c = --decpt) < 0)
+ c = -c;
+ while(c >= 100) {
+ --width;
+ c /= 10;
+ }
+ if (width > 0 && !left) {
+ if (lead0) {
+ if (sign)
+ put(sign)
+ sign = 0;
+ do put('0')
+ while(--width > 0);
+ }
+ else do put(' ')
+ while(--width > 0);
+ }
+ if (sign)
+ put(sign)
+ put(*s++)
+ if (prec || alt)
+ put('.')
+ while(--prec >= 0) {
+ if ((c = *s))
+ s++;
+ else
+ c = '0';
+ put(c)
+ }
+ put(conv)
+ if (decpt < 0) {
+ put('-')
+ decpt = -decpt;
+ }
+ else
+ put('+')
+ for(c = 2, k = 10; 10*k <= decpt; c++, k *= 10);
+ for(;;) {
+ i1 = decpt / k;
+ put(i1 + '0')
+ if (--c <= 0)
+ break;
+ decpt -= i1*k;
+ decpt *= 10;
+ }
+ while(--width >= 0)
+ put(' ')
+ freedtoa(s0);
+ continue;
+#ifndef NO_PRINTF_A_FMT
+ case 'a':
+ digits = hex;
+ goto more_a;
+ case 'A':
+ digits = Hex;
+ more_a:
+#ifdef GDTOA_H_INCLUDED /*{{*/
+ if (fpbits == dfpbits)
+ u.d = va_arg(ap, double);
+#ifdef GDTOA_both /*{*/
+ else if (fpbits == GDTOA_LD_fpbits)
+ u.ld = va_arg(ap, long double);
+ else
+ u.Qd = va_arg(ap, GDTOA_Qtype);
+#else
+ else
+ u.ld = va_arg(ap, long double);
+#endif /*}*/
+#else /*}{*/
+ u.d = va_arg(ap, double);
+#endif /*}}*/
+ fpbits(&u, &fpb);
+ if (fpb.kind == STRTOG_Infinite) {
+ s = "Infinity";
+ s0 = 0;
+ goto fmt9999;
+ }
+ if (fpb.kind == STRTOG_NaN) {
+ s = "NaN";
+ s0 = 0;
+ goto fmt9999;
+ }
+ prec1 = fpiprec(&fpb);
+ if (dot && prec < prec1)
+ prec1 = bround(&fpb, prec, prec1);
+ bw = 1;
+ bex = fpb.ex + 4*prec1;
+ if (bex) {
+ if ((i1 = bex) < 0)
+ i1 = -i1;
+ while(i1 >= 10) {
+ ++bw;
+ i1 /= 10;
+ }
+ }
+ if (fpb.sign && (sign || fpb.kind != STRTOG_Zero))
+ sign = '-';
+ if ((width -= bw + 5) > 0) {
+ if (sign)
+ --width;
+ if (prec1 || alt)
+ --width;
+ }
+ if ((width -= prec1) > 0 && !left && !lead0) {
+ do put(' ')
+ while(--width > 0);
+ }
+ if (sign)
+ put(sign)
+ put('0')
+ put(digits[17])
+ if (lead0 && width > 0 && !left) {
+ do put('0')
+ while(--width > 0);
+ }
+ i1 = prec1 & 7;
+ k = prec1 >> 3;
+ put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
+ if (prec1 > 0 || alt)
+ put('.')
+ if (prec1 > 0) {
+ prec -= prec1;
+ while(prec1 > 0) {
+ if (--i1 < 0) {
+ if (--k < 0)
+ break;
+ i1 = 7;
+ }
+ put(digits[(fpb.bits[k] >> 4*i1) & 0xf])
+ --prec1;
+ }
+ if (alt && prec > 0)
+ do put(0)
+ while(--prec > 0);
+ }
+ put(digits[16])
+ if (bex < 0) {
+ put('-')
+ bex = -bex;
+ }
+ else
+ put('+')
+ for(c = 1; 10*c <= bex; c *= 10);
+ for(;;) {
+ i1 = bex / c;
+ put('0' + i1)
+ if (!--bw)
+ break;
+ bex -= i1 * c;
+ bex *= 10;
+ }
+ while(--width >= 0)
+ put(' ')
+ continue;
+#endif /* NO_PRINTF_A_FMT */
+ default:
+ put('%')
+ while(fmt0 < fmt)
+ put(*fmt0++)
+ continue;
+ }
+ }
+ done:
+ *outbuf = 0;
+ return (f->lastlen = outbuf - ob0) + rv;
+ }
+
+#define Bsize 256
+
+ int
+Printf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *fmt;
+
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap, fmt);
+#endif
+ f.u.cf = stdout;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (stdout == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, stdout);
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ static char *
+Sput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ if (Printf("\nBUG! Sput called!\n", f, rvp))
+ /* pass vp, rvp and return 0 to shut diagnostics off */
+ exit(250);
+ return 0;
+ }
+
+ int
+Sprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *s, *fmt;
+ va_list ap;
+ int rv;
+ Finfo f;
+
+ va_start(ap);
+ s = va_arg(ap, char*);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (char *s, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+
+ va_start(ap, fmt);
+#endif
+ f.ob0 = s;
+ rv = x_sprintf(s, Sput, &f, fmt, ap);
+ va_end(ap);
+ return rv;
+ }
+
+ int
+Fprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ FILE *F;
+ char *s, *fmt;
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap);
+ F = va_arg(ap, FILE*);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (FILE *F, const char *fmt, ...)
+{
+ va_list ap;
+ int rv;
+ Finfo f;
+ char buf[Bsize];
+
+ va_start(ap, fmt);
+#endif
+ f.u.cf = F;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef MESS
+ if (stdout_or_err(F)) {
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ else
+#endif /*MESS*/
+ {
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ int
+Vsprintf
+#ifdef KR_headers
+ (s, fmt, ap) char *s, *fmt; va_list ap;
+#else
+ (char *s, const char *fmt, va_list ap)
+#endif
+{
+ Finfo f;
+ return x_sprintf(f.ob0 = s, Sput, &f, fmt, ap);
+ }
+
+ int
+Vfprintf
+#ifdef KR_headers
+ (F, fmt, ap) FILE *F; char *fmt; va_list ap;
+#else
+ (FILE *F, const char *fmt, va_list ap)
+#endif
+{
+ char buf[Bsize];
+ int rv;
+ Finfo f;
+
+ f.u.cf = F;
+ f.ob0 = buf;
+ f.obe1 = buf + Bsize - 1;
+#ifdef MESS
+ if (stdout_or_err(F)) {
+#ifdef _windows_
+ if (fileno(stdout) == stdout_fileno_ASL) {
+ rv = x_sprintf(f.obe1, Wput, &f, fmt, ap);
+ mwrite(buf, f.lastlen);
+ }
+ else
+#endif
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ else
+#endif /*MESS*/
+ {
+#ifdef PF_BUF
+ if (F == stderr_ASL) {
+ rv = x_sprintf(f.obe1, pfput, &f, fmt, ap);
+ pf_put(buf, f.lastlen);
+ }
+ else
+#endif
+ {
+ rv = x_sprintf(f.obe1, Fput, &f, fmt, ap);
+ fputs(buf, F);
+ }
+ }
+ va_end(ap);
+ return rv;
+ }
+
+ void
+Perror
+#ifdef KR_headers
+ (s) char *s;
+#else
+ (const char *s)
+#endif
+{
+ if (s && *s)
+ Fprintf(Stderr, "%s: ", s);
+ Fprintf(Stderr, "%s\n", strerror(errno));
+ }
+
+ static char *
+Snput
+#ifdef KR_headers
+ (f, rvp) Finfo *f; int *rvp;
+#else
+ (Finfo *f, int *rvp)
+#endif
+{
+ char *s, *s0;
+ size_t L;
+
+ *rvp += Bsize;
+ s0 = f->ob0;
+ s = f->u.sf;
+ if ((L = f->obe1 - s) > Bsize) {
+ L = Bsize;
+ goto copy;
+ }
+ if (L > 0) {
+ copy:
+ memcpy(s, s0, L);
+ f->u.sf = s + L;
+ }
+ return s0;
+ }
+
+ int
+Vsnprintf
+#ifdef KR_headers
+ (s, n, fmt, ap) char *s; size_t n; char *fmt; va_list ap;
+#else
+ (char *s, size_t n, const char *fmt, va_list ap)
+#endif
+{
+ Finfo f;
+ char buf[Bsize];
+ int L, rv;
+
+ if (n <= 0 || !s) {
+ n = 1;
+ s = buf;
+ }
+ f.u.sf = s;
+ f.ob0 = buf;
+ f.obe1 = s + n - 1;
+ rv = x_sprintf(buf + Bsize, Snput, &f, fmt, ap);
+ if (f.lastlen > (L = f.obe1 - f.u.sf))
+ f.lastlen = L;
+ if (f.lastlen > 0) {
+ memcpy(f.u.sf, buf, f.lastlen);
+ f.u.sf += f.lastlen;
+ }
+ *f.u.sf = 0;
+ return rv;
+ }
+ int
+Snprintf
+#ifdef KR_headers
+ (va_alist)
+ va_dcl
+{
+ char *s, *fmt;
+ int rv;
+ size_t n;
+ va_list ap;
+
+ va_start(ap);
+ s = va_arg(ap, char*);
+ n = va_arg(ap, size_t);
+ fmt = va_arg(ap, char*);
+ /*}*/
+#else
+ (char *s, size_t n, const char *fmt, ...)
+{
+ int rv;
+ va_list ap;
+
+ va_start(ap, fmt);
+#endif
+ rv = Vsnprintf(s, n, fmt, ap);
+ va_end(ap);
+ return rv;
+ }
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/contrib/gdtoa/smisc.c b/contrib/gdtoa/smisc.c
index 50431fc..f4dbafb 100644
--- a/contrib/gdtoa/smisc.c
+++ b/contrib/gdtoa/smisc.c
@@ -77,33 +77,33 @@ ratio
(Bigint *a, Bigint *b)
#endif
{
- double da, db;
+ U da, db;
int k, ka, kb;
- dval(da) = b2d(a, &ka);
- dval(db) = b2d(b, &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;
+ word0(&da) += (k >> 2)*Exp_msk1;
if (k &= 3)
- dval(da) *= 1 << k;
+ dval(&da) *= 1 << k;
}
else {
k = -k;
- word0(db) += (k >> 2)*Exp_msk1;
+ word0(&db) += (k >> 2)*Exp_msk1;
if (k &= 3)
- dval(db) *= 1 << k;
+ dval(&db) *= 1 << k;
}
#else
if (k > 0)
- word0(da) += k*Exp_msk1;
+ word0(&da) += k*Exp_msk1;
else {
k = -k;
- word0(db) += k*Exp_msk1;
+ word0(&db) += k*Exp_msk1;
}
#endif
- return dval(da) / dval(db);
+ return dval(&da) / dval(&db);
}
#ifdef INFNAN_CHECK
diff --git a/contrib/gdtoa/stdio1.h b/contrib/gdtoa/stdio1.h
new file mode 100644
index 0000000..ef2bb63
--- /dev/null
+++ b/contrib/gdtoa/stdio1.h
@@ -0,0 +1,103 @@
+/****************************************************************
+Copyright (C) 1997-1999 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.
+****************************************************************/
+
+/* stdio1.h -- for using Printf, Fprintf, Sprintf while
+ * retaining the system-supplied printf, fprintf, sprintf.
+ */
+
+#ifndef STDIO1_H_included
+#define STDIO1_H_included
+#ifndef STDIO_H_included /* allow suppressing stdio.h */
+#include <stdio.h> /* in case it's already included, */
+#endif /* e.g., by cplex.h */
+
+#ifdef KR_headers
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+#define ANSI(x) ()
+#include "varargs.h"
+#ifndef Char
+#define Char char
+#endif
+#else
+#define ANSI(x) x
+#include "stdarg.h"
+#ifndef Char
+#define Char void
+#endif
+#endif
+
+#ifndef NO_STDIO1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int Fprintf ANSI((FILE*, const char*, ...));
+extern int Printf ANSI((const char*, ...));
+extern int Sprintf ANSI((char*, const char*, ...));
+extern int Snprintf ANSI((char*, size_t, const char*, ...));
+extern void Perror ANSI((const char*));
+extern int Vfprintf ANSI((FILE*, const char*, va_list));
+extern int Vsprintf ANSI((char*, const char*, va_list));
+extern int Vsnprintf ANSI((char*, size_t, const char*, va_list));
+
+#ifdef PF_BUF
+extern FILE *stderr_ASL;
+extern void (*pfbuf_print_ASL) ANSI((char*));
+extern char *pfbuf_ASL;
+extern void fflush_ASL ANSI((FILE*));
+#ifdef fflush
+#define old_fflush_ASL fflush
+#undef fflush
+#endif
+#define fflush fflush_ASL
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#undef printf
+#undef fprintf
+#undef sprintf
+#undef perror
+#undef vfprintf
+#undef vsprintf
+#define printf Printf
+#define fprintf Fprintf
+#undef snprintf /* for MacOSX */
+#undef vsnprintf /* for MacOSX */
+#define snprintf Snprintf
+#define sprintf Sprintf
+#define perror Perror
+#define vfprintf Vfprintf
+#define vsnprintf Vsnprintf
+#define vsprintf Vsprintf
+
+#endif /* NO_STDIO1 */
+
+#endif /* STDIO1_H_included */
diff --git a/contrib/gdtoa/strtoIg.c b/contrib/gdtoa/strtoIg.c
index 90c88db..6a17760 100644
--- a/contrib/gdtoa/strtoIg.c
+++ b/contrib/gdtoa/strtoIg.c
@@ -74,7 +74,7 @@ strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp)
goto swapcheck;
}
if (b1->wds > nw
- || nb1 && b1->x[nw1] & 1L << nb1) {
+ || (nb1 && b1->x[nw1] & 1L << nb1)) {
if (++e1 > fpi->emax)
rv1 = STRTOG_Infinite | STRTOG_Inexhi;
rshift(b1, 1);
diff --git a/contrib/gdtoa/strtod.c b/contrib/gdtoa/strtod.c
index 5550853..fe8cde8 100644
--- a/contrib/gdtoa/strtod.c
+++ b/contrib/gdtoa/strtod.c
@@ -59,6 +59,28 @@ static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
#define Rounding Flt_Rounds
#endif
+#ifdef Avoid_Underflow /*{*/
+ static double
+sulp
+#ifdef KR_headers
+ (x, scale) U *x; int scale;
+#else
+ (U *x, int scale)
+#endif
+{
+ U u;
+ double rv;
+ int i;
+
+ rv = ulp(x);
+ if (!scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0)
+ return rv; /* Is there an example where i <= 0 ? */
+ word0(&u) = Exp_1 + (i << Exp_shift);
+ word1(&u) = 0;
+ return rv * u.d;
+ }
+#endif /*}*/
+
double
strtod
#ifdef KR_headers
@@ -73,10 +95,14 @@ strtod
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
CONST char *s, *s0, *s1;
- double aadj, aadj1, adj, rv, rv0;
+ double aadj;
Long L;
+ U adj, aadj1, rv, rv0;
ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
+#ifdef Avoid_Underflow
+ ULong Lsb, Lsb1;
+#endif
#ifdef SET_INEXACT
int inexact, oldinexact;
#endif
@@ -90,7 +116,7 @@ strtod
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
@@ -117,7 +143,7 @@ strtod
#endif /*}*/
sign = nz0 = nz = decpt = 0;
- dval(rv) = 0.;
+ dval(&rv) = 0.;
for(s = s00;;s++) switch(*s) {
case '-':
sign = 1;
@@ -149,20 +175,12 @@ strtod
case 'x':
case 'X':
{
-#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) /*{{*/
+#ifdef Honor_FLT_ROUNDS
FPI fpi1 = fpi;
-#ifdef Honor_FLT_ROUNDS /*{{*/
fpi1.rounding = Rounding;
-#else /*}{*/
- switch(fegetround()) {
- case FE_TOWARDZERO: fpi1.rounding = 0; break;
- case FE_UPWARD: fpi1.rounding = 2; break;
- case FE_DOWNWARD: fpi1.rounding = 3;
- }
-#endif /*}}*/
-#else /*}{*/
+#else
#define fpi1 fpi
-#endif /*}}*/
+#endif
switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) {
case STRTOG_NoNumber:
s = s00;
@@ -287,8 +305,8 @@ strtod
--s;
if (!match(&s,"inity"))
++s;
- word0(rv) = 0x7ff00000;
- word1(rv) = 0;
+ word0(&rv) = 0x7ff00000;
+ word1(&rv) = 0;
goto ret;
}
break;
@@ -299,13 +317,13 @@ strtod
if (*s == '(' /*)*/
&& hexnan(&s, &fpinan, bits)
== STRTOG_NaNbits) {
- word0(rv) = 0x7ff80000 | bits[1];
- word1(rv) = bits[0];
+ word0(&rv) = 0x7ff80000 | bits[1];
+ word1(&rv) = bits[0];
}
else {
#endif
- word0(rv) = NAN_WORD0;
- word1(rv) = NAN_WORD1;
+ word0(&rv) = NAN_WORD0;
+ word1(&rv) = NAN_WORD1;
#ifndef No_Hex_NaN
}
#endif
@@ -329,13 +347,13 @@ strtod
if (!nd0)
nd0 = nd;
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- dval(rv) = y;
+ 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;
+ dval(&rv) = tens[k - 9] * dval(&rv) + z;
}
bd0 = 0;
if (nd <= DBL_DIG
@@ -347,6 +365,7 @@ strtod
) {
if (!e)
goto ret;
+#ifndef ROUND_BIASED_without_Round_Up
if (e > 0) {
if (e <= Ten_pmax) {
#ifdef VAX
@@ -355,11 +374,11 @@ strtod
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ rv.d = -rv.d;
sign = 0;
}
#endif
- /* rv = */ rounded_product(dval(rv), tens[e]);
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
goto ret;
#endif
}
@@ -371,25 +390,25 @@ strtod
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ rv.d = -rv.d;
sign = 0;
}
#endif
e -= i;
- dval(rv) *= tens[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)
+ 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;
+ word0(&rv) += P*Exp_msk1;
#else
- /* rv = */ rounded_product(dval(rv), tens[e]);
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
#endif
goto ret;
}
@@ -399,14 +418,15 @@ strtod
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ rv.d = -rv.d;
sign = 0;
}
#endif
- /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+ /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
goto ret;
}
#endif
+#endif /* ROUND_BIASED_without_Round_Up */
}
e1 += nd - k;
@@ -434,67 +454,73 @@ strtod
if (e1 > 0) {
if ( (i = e1 & 15) !=0)
- dval(rv) *= tens[i];
+ 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;
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
break;
default:
- word0(rv) = Exp_mask;
- word1(rv) = 0;
+ word0(&rv) = Exp_mask;
+ word1(&rv) = 0;
}
#else /*Honor_FLT_ROUNDS*/
- word0(rv) = Exp_mask;
- word1(rv) = 0;
+ word0(&rv) = Exp_mask;
+ word1(&rv) = 0;
#endif /*Honor_FLT_ROUNDS*/
#ifdef SET_INEXACT
/* set overflow bit */
- dval(rv0) = 1e300;
- dval(rv0) *= dval(rv0);
+ dval(&rv0) = 1e300;
+ dval(&rv0) *= dval(&rv0);
#endif
#else /*IEEE_Arith*/
- word0(rv) = Big0;
- word1(rv) = Big1;
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
#endif /*IEEE_Arith*/
- if (bd0)
- goto retfree;
+ range_err:
+ if (bd0) {
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ }
+#ifndef NO_ERRNO
+ errno = ERANGE;
+#endif
goto ret;
}
e1 >>= 4;
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
- dval(rv) *= bigtens[j];
+ dval(&rv) *= bigtens[j];
/* The last multiplication could overflow. */
- word0(rv) -= P*Exp_msk1;
- dval(rv) *= bigtens[j];
- if ((z = word0(rv) & Exp_mask)
+ 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;
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
}
else
- word0(rv) += P*Exp_msk1;
+ word0(&rv) += P*Exp_msk1;
}
}
else if (e1 < 0) {
e1 = -e1;
if ( (i = e1 & 15) !=0)
- dval(rv) /= tens[i];
+ dval(&rv) /= tens[i];
if (e1 >>= 4) {
if (e1 >= 1 << n_bigtens)
goto undfl;
@@ -503,44 +529,39 @@ strtod
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)
+ 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;
+ word1(&rv) = 0;
if (j >= 53)
- word0(rv) = (P+2)*Exp_msk1;
+ word0(&rv) = (P+2)*Exp_msk1;
else
- word0(rv) &= 0xffffffff << j-32;
+ word0(&rv) &= 0xffffffff << (j-32);
}
else
- word1(rv) &= 0xffffffff << j;
+ word1(&rv) &= 0xffffffff << j;
}
#else
for(j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
- dval(rv) *= tinytens[j];
+ 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];
+ dval(&rv0) = dval(&rv);
+ dval(&rv) *= tinytens[j];
+ if (!dval(&rv)) {
+ dval(&rv) = 2.*dval(&rv0);
+ dval(&rv) *= tinytens[j];
#endif
- if (!dval(rv)) {
+ if (!dval(&rv)) {
undfl:
- dval(rv) = 0.;
-#ifndef NO_ERRNO
- errno = ERANGE;
-#endif
- if (bd0)
- goto retfree;
- goto ret;
+ dval(&rv) = 0.;
+ goto range_err;
}
#ifndef Avoid_Underflow
- word0(rv) = Tiny0;
- word1(rv) = Tiny1;
+ word0(&rv) = Tiny0;
+ word1(&rv) = Tiny1;
/* The refinement below will clean
* this approximation up.
*/
@@ -558,7 +579,7 @@ strtod
for(;;) {
bd = Balloc(bd0->k);
Bcopy(bd, bd0);
- bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bb = d2b(dval(&rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
bs = i2b(1);
if (e >= 0) {
@@ -579,12 +600,19 @@ strtod
bs2++;
#endif
#ifdef Avoid_Underflow
+ Lsb = LSB;
+ Lsb1 = 0;
j = bbe - scale;
i = j + bbbits - 1; /* logb(rv) */
- if (i < Emin) /* denormal */
- j += P - Emin;
- else
- j = P + 1 - bbbits;
+ j = P + 1 - bbbits;
+ if (i < Emin) { /* denormal */
+ i = Emin - i;
+ j -= i;
+ if (i < 32)
+ Lsb <<= i;
+ else
+ Lsb1 = Lsb << (i-32);
+ }
#else /*Avoid_Underflow*/
#ifdef Sudden_Underflow
#ifdef IBM
@@ -594,7 +622,7 @@ strtod
#endif
#else /*Sudden_Underflow*/
j = bbe;
- i = j + bbbits - 1; /* logb(rv) */
+ i = j + bbbits - 1; /* logb(&rv) */
if (i < Emin) /* denormal */
j += P - Emin;
else
@@ -645,15 +673,15 @@ strtod
}
if (Rounding) {
if (dsign) {
- adj = 1.;
+ dval(&adj) = 1.;
goto apply_adj;
}
}
else if (!dsign) {
- adj = -1.;
- if (!word1(rv)
- && !(word0(rv) & Frac_mask)) {
- y = word0(rv) & Exp_mask;
+ dval(&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
@@ -662,66 +690,66 @@ strtod
{
delta = lshift(delta,Log2P);
if (cmp(delta, bs) <= 0)
- adj = -0.5;
+ dval(&adj) = -0.5;
}
}
apply_adj:
#ifdef Avoid_Underflow
- if (scale && (y = word0(rv) & Exp_mask)
+ if (scale && (y = word0(&rv) & Exp_mask)
<= 2*P*Exp_msk1)
- word0(adj) += (2*P+1)*Exp_msk1 - y;
+ word0(&adj) += (2*P+1)*Exp_msk1 - y;
#else
#ifdef Sudden_Underflow
- if ((word0(rv) & Exp_mask) <=
+ if ((word0(&rv) & Exp_mask) <=
P*Exp_msk1) {
- word0(rv) += P*Exp_msk1;
- dval(rv) += adj*ulp(dval(rv));
- word0(rv) -= P*Exp_msk1;
+ word0(&rv) += P*Exp_msk1;
+ dval(&rv) += adj*ulp(&rv);
+ word0(&rv) -= P*Exp_msk1;
}
else
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
- dval(rv) += adj*ulp(dval(rv));
+ dval(&rv) += adj.d*ulp(&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) {
+ dval(&adj) = ratio(delta, bs);
+ if (adj.d < 1.)
+ dval(&adj) = 1.;
+ if (adj.d <= 0x7ffffffe) {
+ /* dval(&adj) = Rounding ? ceil(&adj) : floor(&adj); */
+ y = adj.d;
+ if (y != adj.d) {
if (!((Rounding>>1) ^ dsign))
y++;
- adj = y;
+ dval(&adj) = y;
}
}
#ifdef Avoid_Underflow
- if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
- word0(adj) += (2*P+1)*Exp_msk1 - y;
+ 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 ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+ word0(&rv) += P*Exp_msk1;
+ dval(&adj) *= ulp(&rv);
if (dsign)
- dval(rv) += adj;
+ dval(&rv) += adj;
else
- dval(rv) -= adj;
- word0(rv) -= P*Exp_msk1;
+ dval(&rv) -= adj;
+ word0(&rv) -= P*Exp_msk1;
goto cont;
}
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
- adj *= ulp(dval(rv));
+ dval(&adj) *= ulp(&rv);
if (dsign) {
- if (word0(rv) == Big0 && word1(rv) == Big1)
+ if (word0(&rv) == Big0 && word1(&rv) == Big1)
goto ovfl;
- dval(rv) += adj;
+ dval(&rv) += adj.d;
}
else
- dval(rv) -= adj;
+ dval(&rv) -= adj.d;
goto cont;
}
#endif /*Honor_FLT_ROUNDS*/
@@ -730,12 +758,12 @@ strtod
/* 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
+ if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
#ifdef IEEE_Arith
#ifdef Avoid_Underflow
- || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
+ || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
#else
- || (word0(rv) & Exp_mask) <= Exp_msk1
+ || (word0(&rv) & Exp_mask) <= Exp_msk1
#endif
#endif
) {
@@ -760,32 +788,34 @@ strtod
if (i == 0) {
/* exactly half-way between */
if (dsign) {
- if ((word0(rv) & Bndry_mask1) == Bndry_mask1
- && word1(rv) == (
+ if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
+ && word1(&rv) == (
#ifdef Avoid_Underflow
- (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
+ (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)
+ if (word0(&rv) == Big0 && word1(&rv) == Big1)
+ goto ovfl;
+ word0(&rv) = (word0(&rv) & Exp_mask)
+ Exp_msk1
#ifdef IBM
| Exp_msk1 >> 4
#endif
;
- word1(rv) = 0;
+ word1(&rv) = 0;
#ifdef Avoid_Underflow
dsign = 0;
#endif
break;
}
}
- else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+ else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
drop_down:
/* boundary case -- decrement exponent */
#ifdef Sudden_Underflow /*{{*/
- L = word0(rv) & Exp_mask;
+ L = word0(&rv) & Exp_mask;
#ifdef IBM
if (L < Exp_msk1)
#else
@@ -800,7 +830,7 @@ strtod
#else /*Sudden_Underflow}{*/
#ifdef Avoid_Underflow
if (scale) {
- L = word0(rv) & Exp_mask;
+ L = word0(&rv) & Exp_mask;
if (L <= (2*P+1)*Exp_msk1) {
if (L > (P+2)*Exp_msk1)
/* round even ==> */
@@ -811,10 +841,10 @@ strtod
}
}
#endif /*Avoid_Underflow*/
- L = (word0(rv) & Exp_mask) - Exp_msk1;
+ L = (word0(&rv) & Exp_mask) - Exp_msk1;
#endif /*Sudden_Underflow}}*/
- word0(rv) = L | Bndry_mask1;
- word1(rv) = 0xffffffff;
+ word0(&rv) = L | Bndry_mask1;
+ word1(&rv) = 0xffffffff;
#ifdef IBM
goto cont;
#else
@@ -822,16 +852,33 @@ strtod
#endif
}
#ifndef ROUND_BIASED
- if (!(word1(rv) & LSB))
+#ifdef Avoid_Underflow
+ if (Lsb1) {
+ if (!(word0(&rv) & Lsb1))
+ break;
+ }
+ else if (!(word1(&rv) & Lsb))
+ break;
+#else
+ if (!(word1(&rv) & LSB))
break;
#endif
+#endif
if (dsign)
- dval(rv) += ulp(dval(rv));
+#ifdef Avoid_Underflow
+ dval(&rv) += sulp(&rv, scale);
+#else
+ dval(&rv) += ulp(&rv);
+#endif
#ifndef ROUND_BIASED
else {
- dval(rv) -= ulp(dval(rv));
+#ifdef Avoid_Underflow
+ dval(&rv) -= sulp(&rv, scale);
+#else
+ dval(&rv) -= ulp(&rv);
+#endif
#ifndef Sudden_Underflow
- if (!dval(rv))
+ if (!dval(&rv))
goto undfl;
#endif
}
@@ -843,14 +890,14 @@ strtod
}
if ((aadj = ratio(delta, bs)) <= 2.) {
if (dsign)
- aadj = aadj1 = 1.;
- else if (word1(rv) || word0(rv) & Bndry_mask) {
+ aadj = dval(&aadj1) = 1.;
+ else if (word1(&rv) || word0(&rv) & Bndry_mask) {
#ifndef Sudden_Underflow
- if (word1(rv) == Tiny1 && !word0(rv))
+ if (word1(&rv) == Tiny1 && !word0(&rv))
goto undfl;
#endif
aadj = 1.;
- aadj1 = -1.;
+ dval(&aadj1) = -1.;
}
else {
/* special case -- power of FLT_RADIX to be */
@@ -860,45 +907,45 @@ strtod
aadj = 1./FLT_RADIX;
else
aadj *= 0.5;
- aadj1 = -aadj;
+ dval(&aadj1) = -aadj;
}
}
else {
aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
+ dval(&aadj1) = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS
switch(Rounding) {
case 2: /* towards +infinity */
- aadj1 -= 0.5;
+ dval(&aadj1) -= 0.5;
break;
case 0: /* towards 0 */
case 3: /* towards -infinity */
- aadj1 += 0.5;
+ dval(&aadj1) += 0.5;
}
#else
if (Flt_Rounds == 0)
- aadj1 += 0.5;
+ dval(&aadj1) += 0.5;
#endif /*Check_FLT_ROUNDS*/
}
- y = word0(rv) & Exp_mask;
+ 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) >=
+ dval(&rv0) = dval(&rv);
+ word0(&rv) -= P*Exp_msk1;
+ dval(&adj) = dval(&aadj1) * ulp(&rv);
+ dval(&rv) += dval(&adj);
+ if ((word0(&rv) & Exp_mask) >=
Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
- if (word0(rv0) == Big0 && word1(rv0) == Big1)
+ if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
goto ovfl;
- word0(rv) = Big0;
- word1(rv) = Big1;
+ word0(&rv) = Big0;
+ word1(&rv) = Big1;
goto cont;
}
else
- word0(rv) += P*Exp_msk1;
+ word0(&rv) += P*Exp_msk1;
}
else {
#ifdef Avoid_Underflow
@@ -907,58 +954,58 @@ strtod
if ((z = aadj) <= 0)
z = 1;
aadj = z;
- aadj1 = dsign ? aadj : -aadj;
+ dval(&aadj1) = dsign ? aadj : -aadj;
}
- word0(aadj1) += (2*P+1)*Exp_msk1 - y;
+ word0(&aadj1) += (2*P+1)*Exp_msk1 - y;
}
- adj = aadj1 * ulp(dval(rv));
- dval(rv) += adj;
+ dval(&adj) = dval(&aadj1) * ulp(&rv);
+ dval(&rv) += dval(&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;
+ if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) {
+ dval(&rv0) = dval(&rv);
+ word0(&rv) += P*Exp_msk1;
+ dval(&adj) = dval(&aadj1) * ulp(&rv);
+ dval(&rv) += adj;
#ifdef IBM
- if ((word0(rv) & Exp_mask) < P*Exp_msk1)
+ if ((word0(&rv) & Exp_mask) < P*Exp_msk1)
#else
- if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
+ if ((word0(&rv) & Exp_mask) <= P*Exp_msk1)
#endif
{
- if (word0(rv0) == Tiny0
- && word1(rv0) == Tiny1)
+ if (word0(&rv0) == Tiny0
+ && word1(&rv0) == Tiny1)
goto undfl;
- word0(rv) = Tiny0;
- word1(rv) = Tiny1;
+ word0(&rv) = Tiny0;
+ word1(&rv) = Tiny1;
goto cont;
}
else
- word0(rv) -= P*Exp_msk1;
+ word0(&rv) -= P*Exp_msk1;
}
else {
- adj = aadj1 * ulp(dval(rv));
- dval(rv) += adj;
+ dval(&adj) = dval(&aadj1) * ulp(&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.,
+ /* Compute dval(&adj) so that the IEEE rounding rules will
+ * correctly round rv + dval(&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);
+ dval(&aadj1) = (double)(int)(aadj + 0.5);
if (!dsign)
- aadj1 = -aadj1;
+ dval(&aadj1) = -dval(&aadj1);
}
- adj = aadj1 * ulp(dval(rv));
- dval(rv) += adj;
+ dval(&adj) = dval(&aadj1) * ulp(&rv);
+ dval(&rv) += adj;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/
}
- z = word0(rv) & Exp_mask;
+ z = word0(&rv) & Exp_mask;
#ifndef SET_INEXACT
#ifdef Avoid_Underflow
if (!scale)
@@ -968,7 +1015,7 @@ strtod
L = (Long)aadj;
aadj -= L;
/* The tolerances below are conservative. */
- if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+ if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
if (aadj < .4999999 || aadj > .5000001)
break;
}
@@ -982,12 +1029,17 @@ strtod
Bfree(bs);
Bfree(delta);
}
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
#ifdef SET_INEXACT
if (inexact) {
if (!oldinexact) {
- word0(rv0) = Exp_1 + (70 << Exp_shift);
- word1(rv0) = 0;
- dval(rv0) += 1.;
+ word0(&rv0) = Exp_1 + (70 << Exp_shift);
+ word1(&rv0) = 0;
+ dval(&rv0) += 1.;
}
}
else if (!oldinexact)
@@ -995,36 +1047,30 @@ strtod
#endif
#ifdef Avoid_Underflow
if (scale) {
- word0(rv0) = Exp_1 - 2*P*Exp_msk1;
- word1(rv0) = 0;
- dval(rv) *= dval(rv0);
+ 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 */
#ifdef IEEE_Arith
- if (!(word0(rv) & Exp_mask))
+ if (!(word0(&rv) & Exp_mask))
#else
- if (word0(rv) == 0 && word1(rv) == 0)
+ if (word0(&rv) == 0 && word1(&rv) == 0)
#endif
errno = ERANGE;
#endif
}
#endif /* Avoid_Underflow */
#ifdef SET_INEXACT
- if (inexact && !(word0(rv) & Exp_mask)) {
+ if (inexact && !(word0(&rv) & Exp_mask)) {
/* set underflow bit */
- dval(rv0) = 1e-300;
- dval(rv0) *= dval(rv0);
+ 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);
+ return sign ? -dval(&rv) : dval(&rv);
}
diff --git a/contrib/gdtoa/strtodI.c b/contrib/gdtoa/strtodI.c
index 98f8891..0b7b8a4 100644
--- a/contrib/gdtoa/strtodI.c
+++ b/contrib/gdtoa/strtodI.c
@@ -33,16 +33,16 @@ THIS SOFTWARE.
static double
#ifdef KR_headers
-ulpdown(d) double *d;
+ulpdown(d) U *d;
#else
-ulpdown(double *d)
+ulpdown(U *d)
#endif
{
double u;
- ULong *L = (ULong*)d;
+ ULong *L = d->L;
- u = ulp(*d);
- if (!(L[_1] | L[_0] & 0xfffff)
+ u = ulp(d);
+ if (!(L[_1] | (L[_0] & 0xfffff))
&& (L[_0] & 0x7ff00000) > 0x00100000)
u *= 0.5;
return u;
@@ -59,10 +59,6 @@ strtodI(CONST char *s, char **sp, double *dd)
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);
@@ -70,17 +66,17 @@ strtodI(CONST char *s, char **sp, double *dd)
sign = k & STRTOG_Neg ? 0x80000000L : 0;
switch(k & STRTOG_Retmask) {
case STRTOG_NoNumber:
- u->d[0] = u->d[1] = 0.;
+ dval(&u[0]) = dval(&u[1]) = 0.;
break;
case STRTOG_Zero:
- u->d[0] = u->d[1] = 0.;
+ dval(&u[0]) = dval(&u[1]) = 0.;
#ifdef Sudden_Underflow
if (k & STRTOG_Inexact) {
if (sign)
- u->L[_0] = 0x80100000L;
+ word0(&u[0]) = 0x80100000L;
else
- u->L[2+_0] = 0x100000L;
+ word0(&u[1]) = 0x100000L;
}
break;
#else
@@ -88,80 +84,80 @@ strtodI(CONST char *s, char **sp, double *dd)
#endif
case STRTOG_Denormal:
- u->L[_1] = bits[0];
- u->L[_0] = bits[1];
+ word1(&u[0]) = bits[0];
+ word0(&u[0]) = bits[1];
goto contain;
case STRTOG_Normal:
- u->L[_1] = bits[0];
- u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
+ word1(&u[0]) = bits[0];
+ word0(&u[0]) = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20);
contain:
j = k & STRTOG_Inexact;
if (sign) {
- u->L[_0] |= sign;
+ word0(&u[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;
+ word0(&u[1]) = word0(&u[0]) + 0x3500000;
+ word1(&u[1]) = word1(&u[0]);
+ dval(&u[1]) += ulp(&u[1]);
+ word0(&u[1]) -= 0x3500000;
+ if (!(word0(&u[1]) & 0x7ff00000)) {
+ word0(&u[1]) = sign;
+ word1(&u[1]) = 0;
}
}
else
#endif
- u->d[1] = u->d[0] + ulp(u->d[0]);
+ dval(&u[1]) = dval(&u[0]) + ulp(&u[0]);
break;
case STRTOG_Inexhi:
- u->d[1] = u->d[0];
+ dval(&u[1]) = dval(&u[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;
+ if ((word0(&u[0]) & 0x7ff00000) < 0x3500000) {
+ word0(&u[0]) += 0x3500000;
+ dval(&u[0]) -= ulpdown(u);
+ word0(&u[0]) -= 0x3500000;
+ if (!(word0(&u[0]) & 0x7ff00000)) {
+ word0(&u[0]) = sign;
+ word1(&u[0]) = 0;
}
}
else
#endif
- u->d[0] -= ulpdown(u->d);
+ dval(&u[0]) -= ulpdown(u);
break;
default:
- u->d[1] = u->d[0];
+ dval(&u[1]) = dval(&u[0]);
}
break;
case STRTOG_Infinite:
- u->L[_0] = u->L[2+_0] = sign | 0x7ff00000;
- u->L[_1] = u->L[2+_1] = 0;
+ word0(&u[0]) = word0(&u[1]) = sign | 0x7ff00000;
+ word1(&u[0]) = word1(&u[1]) = 0;
if (k & STRTOG_Inexact) {
if (sign) {
- u->L[2+_0] = 0xffefffffL;
- u->L[2+_1] = 0xffffffffL;
+ word0(&u[1]) = 0xffefffffL;
+ word1(&u[1]) = 0xffffffffL;
}
else {
- u->L[_0] = 0x7fefffffL;
- u->L[_1] = 0xffffffffL;
+ word0(&u[0]) = 0x7fefffffL;
+ word1(&u[0]) = 0xffffffffL;
}
}
break;
case STRTOG_NaN:
- u->L[0] = u->L[2] = d_QNAN0;
- u->L[1] = u->L[3] = d_QNAN1;
+ u->L[0] = (u+1)->L[0] = d_QNAN0;
+ u->L[1] = (u+1)->L[1] = d_QNAN1;
break;
case STRTOG_NaNbits:
- u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1];
- u->L[_1] = u->L[2+_1] = bits[0];
+ word0(&u[0]) = word0(&u[1]) = 0x7ff00000 | sign | bits[1];
+ word1(&u[0]) = word1(&u[1]) = bits[0];
}
return k;
}
diff --git a/contrib/gdtoa/strtodg.c b/contrib/gdtoa/strtodg.c
index a69ce30..5059869 100644
--- a/contrib/gdtoa/strtodg.c
+++ b/contrib/gdtoa/strtodg.c
@@ -172,9 +172,9 @@ set_ones(Bigint *b, int n)
rvOK
#ifdef KR_headers
(d, fpi, exp, bits, exact, rd, irv)
- double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv;
+ U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv;
#else
- (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
+ (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
#endif
{
Bigint *b;
@@ -182,7 +182,7 @@ rvOK
int bdif, e, j, k, k1, nb, rv;
carry = rv = 0;
- b = d2b(d, &e, &bdif);
+ b = d2b(dval(d), &e, &bdif);
bdif -= nb = fpi->nbits;
e += bdif;
if (bdif <= 0) {
@@ -291,9 +291,9 @@ rvOK
static int
#ifdef KR_headers
-mantbits(d) double d;
+mantbits(d) U *d;
#else
-mantbits(double d)
+mantbits(U *d)
#endif
{
ULong L;
@@ -327,8 +327,9 @@ strtodg
int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign;
int sudden_underflow;
CONST char *s, *s0, *s1;
- double adj, adj0, rv, tol;
+ double adj0, tol;
Long L;
+ U adj, rv;
ULong *b, *be, y, z;
Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0;
#ifdef USE_LOCALE /*{{*/
@@ -341,7 +342,7 @@ strtodg
static int dplen;
if (!(s0 = decimalpoint_cache)) {
s0 = localeconv()->decimal_point;
- if ((decimalpoint_cache = (char*)malloc(strlen(s0) + 1))) {
+ if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
strcpy(decimalpoint_cache, s0);
s0 = decimalpoint_cache;
}
@@ -355,7 +356,7 @@ strtodg
irv = STRTOG_Zero;
denorm = sign = nz0 = nz = 0;
- dval(rv) = 0.;
+ dval(&rv) = 0.;
rvb = 0;
nbits = fpi->nbits;
for(s = s00;;s++) switch(*s) {
@@ -547,13 +548,13 @@ strtodg
if (!nd0)
nd0 = nd;
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
- dval(rv) = y;
+ dval(&rv) = y;
if (k > 9)
- dval(rv) = tens[k - 9] * dval(rv) + z;
+ dval(&rv) = tens[k - 9] * dval(&rv) + z;
bd0 = 0;
if (nbits <= P && nd <= DBL_DIG) {
if (!e) {
- if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv))
+ if (rvOK(&rv, fpi, exp, bits, 1, rd, &irv))
goto ret;
}
else if (e > 0) {
@@ -561,9 +562,9 @@ strtodg
#ifdef VAX
goto vax_ovfl_check;
#else
- i = fivesbits[e] + mantbits(dval(rv)) <= P;
- /* rv = */ rounded_product(dval(rv), tens[e]);
- if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv))
+ i = fivesbits[e] + mantbits(&rv) <= P;
+ /* rv = */ rounded_product(dval(&rv), tens[e]);
+ if (rvOK(&rv, fpi, exp, bits, i, rd, &irv))
goto ret;
e1 -= e;
goto rv_notOK;
@@ -576,32 +577,32 @@ strtodg
*/
e2 = e - i;
e1 -= i;
- dval(rv) *= tens[i];
+ dval(&rv) *= tens[i];
#ifdef VAX
/* VAX exponent range is so narrow we must
* worry about overflow here...
*/
vax_ovfl_check:
- dval(adj) = dval(rv);
- word0(adj) -= P*Exp_msk1;
- /* adj = */ rounded_product(dval(adj), tens[e2]);
- if ((word0(adj) & Exp_mask)
+ dval(&adj) = dval(&rv);
+ word0(&adj) -= P*Exp_msk1;
+ /* adj = */ rounded_product(dval(&adj), tens[e2]);
+ if ((word0(&adj) & Exp_mask)
> Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
goto rv_notOK;
- word0(adj) += P*Exp_msk1;
- dval(rv) = dval(adj);
+ word0(&adj) += P*Exp_msk1;
+ dval(&rv) = dval(&adj);
#else
- /* rv = */ rounded_product(dval(rv), tens[e2]);
+ /* rv = */ rounded_product(dval(&rv), tens[e2]);
#endif
- if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv))
+ if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv))
goto ret;
e1 -= e2;
}
}
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax) {
- /* rv = */ rounded_quotient(dval(rv), tens[-e]);
- if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv))
+ /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
+ if (rvOK(&rv, fpi, exp, bits, 0, rd, &irv))
goto ret;
e1 -= e;
}
@@ -615,45 +616,45 @@ strtodg
e2 = 0;
if (e1 > 0) {
if ( (i = e1 & 15) !=0)
- dval(rv) *= tens[i];
+ dval(&rv) *= tens[i];
if (e1 &= ~15) {
e1 >>= 4;
- while(e1 >= (1 << n_bigtens-1)) {
- e2 += ((word0(rv) & Exp_mask)
+ while(e1 >= (1 << (n_bigtens-1))) {
+ e2 += ((word0(&rv) & Exp_mask)
>> Exp_shift1) - Bias;
- word0(rv) &= ~Exp_mask;
- word0(rv) |= Bias << Exp_shift1;
- dval(rv) *= bigtens[n_bigtens-1];
- e1 -= 1 << n_bigtens-1;
+ word0(&rv) &= ~Exp_mask;
+ word0(&rv) |= Bias << Exp_shift1;
+ dval(&rv) *= bigtens[n_bigtens-1];
+ e1 -= 1 << (n_bigtens-1);
}
- e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
- word0(rv) &= ~Exp_mask;
- word0(rv) |= Bias << Exp_shift1;
+ e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(&rv) &= ~Exp_mask;
+ word0(&rv) |= Bias << Exp_shift1;
for(j = 0; e1 > 0; j++, e1 >>= 1)
if (e1 & 1)
- dval(rv) *= bigtens[j];
+ dval(&rv) *= bigtens[j];
}
}
else if (e1 < 0) {
e1 = -e1;
if ( (i = e1 & 15) !=0)
- dval(rv) /= tens[i];
+ dval(&rv) /= tens[i];
if (e1 &= ~15) {
e1 >>= 4;
- while(e1 >= (1 << n_bigtens-1)) {
- e2 += ((word0(rv) & Exp_mask)
+ while(e1 >= (1 << (n_bigtens-1))) {
+ e2 += ((word0(&rv) & Exp_mask)
>> Exp_shift1) - Bias;
- word0(rv) &= ~Exp_mask;
- word0(rv) |= Bias << Exp_shift1;
- dval(rv) *= tinytens[n_bigtens-1];
- e1 -= 1 << n_bigtens-1;
+ word0(&rv) &= ~Exp_mask;
+ word0(&rv) |= Bias << Exp_shift1;
+ dval(&rv) *= tinytens[n_bigtens-1];
+ e1 -= 1 << (n_bigtens-1);
}
- e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias;
- word0(rv) &= ~Exp_mask;
- word0(rv) |= Bias << Exp_shift1;
+ e2 += ((word0(&rv) & Exp_mask) >> Exp_shift1) - Bias;
+ word0(&rv) &= ~Exp_mask;
+ word0(&rv) |= Bias << Exp_shift1;
for(j = 0; e1 > 0; j++, e1 >>= 1)
if (e1 & 1)
- dval(rv) *= tinytens[j];
+ dval(&rv) *= tinytens[j];
}
}
#ifdef IBM
@@ -664,7 +665,7 @@ strtodg
*/
e2 <<= 2;
#endif
- rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */
+ rvb = d2b(dval(&rv), &rve, &rvbits); /* rv = rvb * 2^rve */
rve += e2;
if ((j = rvbits - nbits) > 0) {
rshift(rvb, j);
@@ -842,7 +843,7 @@ strtodg
}
else
irv = STRTOG_Normal | STRTOG_Inexhi;
- if (bbbits < nbits && !denorm || !(rvb->x[0] & 1))
+ if ((bbbits < nbits && !denorm) || !(rvb->x[0] & 1))
break;
if (dsign) {
rvb = increment(rvb);
@@ -859,7 +860,7 @@ strtodg
}
break;
}
- if ((dval(adj) = ratio(delta, bs)) <= 2.) {
+ if ((dval(&adj) = ratio(delta, bs)) <= 2.) {
adj1:
inex = STRTOG_Inexlo;
if (dsign) {
@@ -873,15 +874,15 @@ strtodg
irv = STRTOG_Underflow | STRTOG_Inexlo;
break;
}
- adj0 = dval(adj) = 1.;
+ adj0 = dval(&adj) = 1.;
}
else {
- adj0 = dval(adj) *= 0.5;
+ adj0 = dval(&adj) *= 0.5;
if (dsign) {
asub = 0;
inex = STRTOG_Inexlo;
}
- if (dval(adj) < 2147483647.) {
+ if (dval(&adj) < 2147483647.) {
L = adj0;
adj0 -= L;
switch(rd) {
@@ -900,12 +901,12 @@ strtodg
inex = STRTOG_Inexact - inex;
}
}
- dval(adj) = L;
+ dval(&adj) = L;
}
}
y = rve + rvbits;
- /* adj *= ulp(dval(rv)); */
+ /* adj *= ulp(dval(&rv)); */
/* if (asub) rv -= adj; else rv += adj; */
if (!denorm && rvbits < nbits) {
@@ -913,7 +914,7 @@ strtodg
rve -= j;
rvbits = nbits;
}
- ab = d2b(dval(adj), &abe, &abits);
+ ab = d2b(dval(&adj), &abe, &abits);
if (abe < 0)
rshift(ab, -abe);
else if (abe > 0)
@@ -967,15 +968,15 @@ strtodg
z = rve + rvbits;
if (y == z && L) {
/* Can we stop now? */
- tol = dval(adj) * 5e-16; /* > max rel error */
- dval(adj) = adj0 - .5;
- if (dval(adj) < -tol) {
+ tol = dval(&adj) * 5e-16; /* > max rel error */
+ dval(&adj) = adj0 - .5;
+ if (dval(&adj) < -tol) {
if (adj0 > tol) {
irv |= inex;
break;
}
}
- else if (dval(adj) > tol && adj0 < 1. - tol) {
+ else if (dval(&adj) > tol && adj0 < 1. - tol) {
irv |= inex;
break;
}
diff --git a/contrib/gdtoa/strtof.c b/contrib/gdtoa/strtof.c
index df9a75a..84bfe24 100644
--- a/contrib/gdtoa/strtof.c
+++ b/contrib/gdtoa/strtof.c
@@ -59,7 +59,7 @@ strtof(CONST char *s, char **sp)
break;
case STRTOG_Normal:
- u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ u.L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break;
case STRTOG_NaNbits:
diff --git a/contrib/gdtoa/strtopdd.c b/contrib/gdtoa/strtopdd.c
index c665976..738372d 100644
--- a/contrib/gdtoa/strtopdd.c
+++ b/contrib/gdtoa/strtopdd.c
@@ -67,8 +67,8 @@ strtopdd(CONST char *s, char **sp, double *dd)
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;
+ 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;
@@ -79,7 +79,7 @@ strtopdd(CONST char *s, char **sp, double *dd)
else
exp -= i;
if (i > 0) {
- bits[1] = bits[1] << i | bits[0] >> 32-i;
+ bits[1] = bits[1] << i | bits[0] >> (32-i);
bits[0] = bits[0] << i & 0xffffffffL;
}
}
@@ -92,11 +92,11 @@ strtopdd(CONST char *s, char **sp, double *dd)
else
exp -= i;
if (i < 32) {
- bits[1] = bits[0] >> 32 - i;
+ bits[1] = bits[0] >> (32 - i);
bits[0] = bits[0] << i & 0xffffffffL;
}
else {
- bits[1] = bits[0] << i - 32;
+ bits[1] = bits[0] << (i - 32);
bits[0] = 0;
}
}
@@ -105,7 +105,7 @@ strtopdd(CONST char *s, char **sp, double *dd)
break;
}
u->L[2+_1] = bits[0];
- u->L[2+_0] = bits[1] & 0xfffff | exp << 20;
+ u->L[2+_0] = (bits[1] & 0xfffff) | (exp << 20);
break;
case STRTOG_Denormal:
@@ -124,10 +124,10 @@ strtopdd(CONST char *s, char **sp, double *dd)
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[_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+_0] = bits[1] & ((1L << j) - 1);
u->L[2+_1] = bits[0];
break;
@@ -136,34 +136,34 @@ strtopdd(CONST char *s, char **sp, double *dd)
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[_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[_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[_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;
+ 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[_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;
+ u->L[2+_1] = bits[0] & ((1L << j) - 1);
break;
case STRTOG_Infinite:
diff --git a/contrib/gdtoa/strtopf.c b/contrib/gdtoa/strtopf.c
index 74694a0..23ca5cb 100644
--- a/contrib/gdtoa/strtopf.c
+++ b/contrib/gdtoa/strtopf.c
@@ -58,7 +58,7 @@ strtopf(CONST char *s, char **sp, float *f)
case STRTOG_Normal:
case STRTOG_NaNbits:
- L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break;
case STRTOG_Denormal:
diff --git a/contrib/gdtoa/strtopx.c b/contrib/gdtoa/strtopx.c
index 07d0458..f7a25ff 100644
--- a/contrib/gdtoa/strtopx.c
+++ b/contrib/gdtoa/strtopx.c
@@ -92,7 +92,8 @@ strtopx(CONST char *s, char **sp, void *V)
case STRTOG_Infinite:
L[_0] = 0x7fff;
- L[_1] = L[_2] = L[_3] = L[_4] = 0;
+ L[_1] = 0x8000;
+ L[_2] = L[_3] = L[_4] = 0;
break;
case STRTOG_NaN:
diff --git a/contrib/gdtoa/strtopxL.c b/contrib/gdtoa/strtopxL.c
index b0f5cdd..6519a41 100644
--- a/contrib/gdtoa/strtopxL.c
+++ b/contrib/gdtoa/strtopxL.c
@@ -82,7 +82,8 @@ strtopxL(CONST char *s, char **sp, void *V)
case STRTOG_Infinite:
L[_0] = 0x7fff << 16;
- L[_1] = L[_2] = 0;
+ L[_1] = 0x80000000;
+ L[_2] = 0;
break;
case STRTOG_NaN:
diff --git a/contrib/gdtoa/strtordd.c b/contrib/gdtoa/strtordd.c
index 9c2b46e..e0b8e6a 100644
--- a/contrib/gdtoa/strtordd.c
+++ b/contrib/gdtoa/strtordd.c
@@ -48,8 +48,8 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
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;
+ 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;
@@ -60,7 +60,7 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
else
exp -= i;
if (i > 0) {
- bits[1] = bits[1] << i | bits[0] >> 32-i;
+ bits[1] = bits[1] << i | bits[0] >> (32-i);
bits[0] = bits[0] << i & (ULong)0xffffffffL;
}
}
@@ -73,11 +73,11 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
else
exp -= i;
if (i < 32) {
- bits[1] = bits[0] >> 32 - i;
+ bits[1] = bits[0] >> (32 - i);
bits[0] = bits[0] << i & (ULong)0xffffffffL;
}
else {
- bits[1] = bits[0] << i - 32;
+ bits[1] = bits[0] << (i - 32);
bits[0] = 0;
}
}
@@ -86,7 +86,7 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
break;
}
L[2+_1] = bits[0];
- L[2+_0] = bits[1] & 0xfffff | exp << 20;
+ L[2+_0] = (bits[1] & 0xfffff) | (exp << 20);
break;
case STRTOG_Denormal:
@@ -105,10 +105,10 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
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[_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+_0] = bits[1] & (((ULong)1L << j) - 1);
L[2+_1] = bits[0];
break;
@@ -117,34 +117,34 @@ ULtodd(ULong *L, ULong *bits, Long exp, int k)
if (i < 0) {
j = -i;
i += 32;
- L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20;
+ 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+_0] = bits[1] & (((ULong)1L << j) - 1);
L[2+_1] = bits[0];
break;
}
if (i == 0) {
- L[_0] = bits[2] & 0xfffff | 33 << 20;
+ 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[_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;
+ 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[_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;
+ L[2+_1] = bits[0] & (((ULong)1L << j) - 1);
break;
case STRTOG_Infinite:
diff --git a/contrib/gdtoa/strtorf.c b/contrib/gdtoa/strtorf.c
index 46b0ba2..21c6d28 100644
--- a/contrib/gdtoa/strtorf.c
+++ b/contrib/gdtoa/strtorf.c
@@ -46,7 +46,7 @@ ULtof(ULong *L, ULong *bits, Long exp, int k)
case STRTOG_Normal:
case STRTOG_NaNbits:
- L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23;
+ L[0] = (bits[0] & 0x7fffff) | ((exp + 0x7f + 23) << 23);
break;
case STRTOG_Denormal:
diff --git a/contrib/gdtoa/strtorx.c b/contrib/gdtoa/strtorx.c
index e9fd45f..cd938f1 100644
--- a/contrib/gdtoa/strtorx.c
+++ b/contrib/gdtoa/strtorx.c
@@ -89,7 +89,8 @@ ULtox(UShort *L, ULong *bits, Long exp, int k)
case STRTOG_Infinite:
L[_0] = 0x7fff;
- L[_1] = L[_2] = L[_3] = L[_4] = 0;
+ L[_1] = 0x8000;
+ L[_2] = L[_3] = L[_4] = 0;
break;
case STRTOG_NaN:
diff --git a/contrib/gdtoa/strtorxL.c b/contrib/gdtoa/strtorxL.c
index ff62a61..58acc80 100644
--- a/contrib/gdtoa/strtorxL.c
+++ b/contrib/gdtoa/strtorxL.c
@@ -70,7 +70,8 @@ ULtoxL(ULong *L, ULong *bits, Long exp, int k)
case STRTOG_Infinite:
L[_0] = 0x7fff << 16;
- L[_1] = L[_2] = 0;
+ L[_1] = 0x80000000;
+ L[_2] = 0;
break;
case STRTOG_NaN:
diff --git a/contrib/gdtoa/ulp.c b/contrib/gdtoa/ulp.c
index 7810a5c..17e9f86 100644
--- a/contrib/gdtoa/ulp.c
+++ b/contrib/gdtoa/ulp.c
@@ -34,13 +34,13 @@ THIS SOFTWARE.
double
ulp
#ifdef KR_headers
- (x) double x;
+ (x) U *x;
#else
- (double x)
+ (U *x)
#endif
{
Long L;
- double a;
+ U a;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Sudden_Underflow
@@ -49,22 +49,22 @@ ulp
#ifdef IBM
L |= Exp_msk1 >> 4;
#endif
- word0(a) = L;
- word1(a) = 0;
+ 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;
+ word0(&a) = 0x80000 >> L;
+ word1(&a) = 0;
}
else {
- word0(a) = 0;
+ word0(&a) = 0;
L -= Exp_shift;
- word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+ word1(&a) = L >= 31 ? 1 : 1 << (31 - L);
}
}
#endif
- return a;
+ return dval(&a);
}
OpenPOWER on IntegriCloud