****************************************************************/
-/* $FreeBSD: src/contrib/gdtoa/gdtoaimp.h,v 1.5 2003/04/09 06:04:35 das Exp $ */
-
/* This is a variation on dtoa.c that converts arbitary binary
floating-point formats to and from decimal notation. It uses
double-precision arithmetic internally, so there are still
double-precision arithmetic (any of IEEE, VAX D_floating,
or IBM mainframe arithmetic).
- Please send bug reports to
- David M. Gay
- Bell Laboratories, Room 2C-463
- 600 Mountain Avenue
- Murray Hill, NJ 07974-0636
- U.S.A.
- dmg@bell-labs.com
+ Please send bug reports to David M. Gay (dmg at acm dot org,
+ with " at " changed at "@" and " dot " changed to ".").
*/
/* On a machine with IEEE extended-precision registers, it is
* biased rounding (add half and chop).
*
* Inspired loosely by William D. Clinger's paper "How to Read Floating
- * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126].
*
* Modifications:
*
* 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with
* 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate.
* #define INFNAN_CHECK on IEEE systems to cause strtod to check for
- * Infinity and NaN (case insensitively). On some systems (e.g.,
- * some HP systems), it may be necessary to #define NAN_WORD0
- * appropriately -- to the most significant word of a quiet NaN.
- * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ * Infinity and NaN (case insensitively).
* When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined,
* strtodg also accepts (case insensitively) strings of the form
* NaN(x), where x is a string of hexadecimal digits and spaces;
#ifndef GDTOAIMP_H_INCLUDED
#define GDTOAIMP_H_INCLUDED
#include "gdtoa.h"
+#include "gd_qnan.h"
#ifdef DEBUG
#include "stdio.h"
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif
-#include "limits.h"
#include "stdlib.h"
#include "string.h"
-#include "libc_private.h"
-#include "spinlock.h"
#ifdef KR_headers
#define Char char
#define MALLOC malloc
#endif
-#define INFNAN_CHECK
-#define USE_LOCALE
-
#undef IEEE_Arith
#undef Avoid_Underflow
#ifdef IEEE_MC68k
#define ALL_ON 0xffff
#endif
-#define MULTIPLE_THREADS
-extern spinlock_t __gdtoa_locks[2];
-#define ACQUIRE_DTOA_LOCK(n) do { \
- if (__isthreaded) \
- _SPINLOCK(&__gdtoa_locks[n]); \
-} while(0)
-#define FREE_DTOA_LOCK(n) do { \
- if (__isthreaded) \
- _SPINUNLOCK(&__gdtoa_locks[n]); \
-} while(0)
+#ifndef MULTIPLE_THREADS
+#define ACQUIRE_DTOA_LOCK(n) /*nothing*/
+#define FREE_DTOA_LOCK(n) /*nothing*/
+#endif
#define Kmax 15
#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int))
#endif /* NO_STRING_H */
-/*
- * Paranoia: Protect exported symbols, including ones in files we don't
- * compile right now. The standard strtof and strtod survive.
- */
-#define dtoa __dtoa
-#define gdtoa __gdtoa
-#define freedtoa __freedtoa
-#define strtodg __strtodg
-#define g_ddfmt __g_ddfmt
-#define g_dfmt __g_dfmt
-#define g_ffmt __g_ffmt
-#define g_Qfmt __g_Qfmt
-#define g_xfmt __g_xfmt
-#define g_xLfmt __g_xLfmt
-#define strtoId __strtoId
-#define strtoIdd __strtoIdd
-#define strtoIf __strtoIf
-#define strtoIQ __strtoIQ
-#define strtoIx __strtoIx
-#define strtoIxL __strtoIxL
-#define strtord __strtord
-#define strtordd __strtordd
-#define strtorf __strtorf
-#define strtorQ __strtorQ
-#define strtorx __strtorx
-#define strtorxL __strtorxL
-#define strtodI __strtodI
-#define strtopd __strtopd
-#define strtopdd __strtopdd
-#define strtopf __strtopf
-#define strtopQ __strtopQ
-#define strtopx __strtopx
-#define strtopxL __strtopxL
-
-/* Protect gdtoa-internal symbols */
-#define Balloc __Balloc_D2A
-#define Bfree __Bfree_D2A
-#define ULtoQ __ULtoQ_D2A
-#define ULtof __ULtof_D2A
-#define ULtod __ULtod_D2A
-#define ULtodd __ULtodd_D2A
-#define ULtox __ULtox_D2A
-#define ULtoxL __ULtoxL_D2A
-#define any_on __any_on_D2A
-#define b2d __b2d_D2A
-#define bigtens __bigtens_D2A
-#define cmp __cmp_D2A
-#define copybits __copybits_D2A
-#define d2b __d2b_D2A
-#define decrement __decrement_D2A
-#define diff __diff_D2A
-#define dtoa_result __dtoa_result_D2A
-#define g__fmt __g__fmt_D2A
-#define gethex __gethex_D2A
-#define hexdig __hexdig_D2A
-#define hexdig_init_D2A __hexdig_init_D2A
-#define hexnan __hexnan_D2A
-#define hi0bits __hi0bits_D2A
-#define i2b __i2b_D2A
-#define increment __increment_D2A
-#define lo0bits __lo0bits_D2A
-#define lshift __lshift_D2A
-#define match __match_D2A
-#define mult __mult_D2A
-#define multadd __multadd_D2A
-#define nrv_alloc __nrv_alloc_D2A
-#define pow5mult __pow5mult_D2A
-#define quorem __quorem_D2A
-#define ratio __ratio_D2A
-#define rshift __rshift_D2A
-#define rv_alloc __rv_alloc_D2A
-#define s2b __s2b_D2A
-#define set_ones __set_ones_D2A
-#define strcp __strcp_D2A
-#define strcp_D2A __strcp_D2A
-#define strtoIg __strtoIg_D2A
-#define sum __sum_D2A
-#define tens __tens_D2A
-#define tinytens __tinytens_D2A
-#define tinytens __tinytens_D2A
-#define trailz __trailz_D2A
-#define ulp __ulp_D2A
+#define Balloc Balloc_D2A
+#define Bfree Bfree_D2A
+#define ULtoQ ULtoQ_D2A
+#define ULtof ULtof_D2A
+#define ULtod ULtod_D2A
+#define ULtodd ULtodd_D2A
+#define ULtox ULtox_D2A
+#define ULtoxL ULtoxL_D2A
+#define any_on any_on_D2A
+#define b2d b2d_D2A
+#define bigtens bigtens_D2A
+#define cmp cmp_D2A
+#define copybits copybits_D2A
+#define d2b d2b_D2A
+#define decrement decrement_D2A
+#define diff diff_D2A
+#define dtoa_result dtoa_result_D2A
+#define g__fmt g__fmt_D2A
+#define gethex gethex_D2A
+#define hexdig hexdig_D2A
+#define hexnan hexnan_D2A
+#define hi0bits(x) hi0bits_D2A((ULong)(x))
+#define i2b i2b_D2A
+#define increment increment_D2A
+#define lo0bits lo0bits_D2A
+#define lshift lshift_D2A
+#define match match_D2A
+#define mult mult_D2A
+#define multadd multadd_D2A
+#define nrv_alloc nrv_alloc_D2A
+#define pow5mult pow5mult_D2A
+#define quorem quorem_D2A
+#define ratio ratio_D2A
+#define rshift rshift_D2A
+#define rv_alloc rv_alloc_D2A
+#define s2b s2b_D2A
+#define set_ones set_ones_D2A
+#define strcp strcp_D2A
+#define strtoIg strtoIg_D2A
+#define sum sum_D2A
+#define tens tens_D2A
+#define tinytens tinytens_D2A
+#define tinytens tinytens_D2A
+#define trailz trailz_D2A
+#define ulp ulp_D2A
extern char *dtoa_result;
extern CONST double bigtens[], tens[], tinytens[];
extern Bigint *diff ANSI((Bigint*, Bigint*));
extern char *dtoa ANSI((double d, int mode, int ndigits,
int *decpt, int *sign, char **rve));
- extern void freedtoa ANSI((char*));
- extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp,
- int mode, int ndigits, int *decpt, char **rve));
extern char *g__fmt ANSI((char*, char*, char*, int, ULong));
extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int));
extern void hexdig_init_D2A(Void);
extern int hexnan ANSI((CONST char**, FPI*, ULong*));
- extern int hi0bits ANSI((ULong));
+ extern int hi0bits_D2A ANSI((ULong));
extern Bigint *i2b ANSI((int));
extern Bigint *increment ANSI((Bigint*));
extern int lo0bits ANSI((ULong*));
extern Bigint *s2b ANSI((CONST char*, int, int, ULong));
extern Bigint *set_ones ANSI((Bigint*, int));
extern char *strcp ANSI((char*, const char*));
- extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*));
-
- extern int strtoId ANSI((CONST char *, char **, double *, double *));
- extern int strtoIdd ANSI((CONST char *, char **, double *, double *));
- extern int strtoIf ANSI((CONST char *, char **, float *, float *));
extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*));
- extern int strtoIQ ANSI((CONST char *, char **, void *, void *));
- extern int strtoIx ANSI((CONST char *, char **, void *, void *));
- extern int strtoIxL ANSI((CONST char *, char **, void *, void *));
extern double strtod ANSI((const char *s00, char **se));
- extern int strtopQ ANSI((CONST char *, char **, Void *));
- extern int strtopf ANSI((CONST char *, char **, float *));
- extern int strtopd ANSI((CONST char *, char **, double *));
- extern int strtopdd ANSI((CONST char *, char **, double *));
- extern int strtopx ANSI((CONST char *, char **, Void *));
- extern int strtopxL ANSI((CONST char *, char **, Void *));
- extern int strtord ANSI((CONST char *, char **, int, double *));
- extern int strtordd ANSI((CONST char *, char **, int, double *));
- extern int strtorf ANSI((CONST char *, char **, int, float *));
- extern int strtorQ ANSI((CONST char *, char **, int, void *));
- extern int strtorx ANSI((CONST char *, char **, int, void *));
- extern int strtorxL ANSI((CONST char *, char **, int, void *));
extern Bigint *sum ANSI((Bigint*, Bigint*));
extern int trailz ANSI((Bigint*));
extern double ulp ANSI((double));
#ifdef __cplusplus
}
#endif
-
-
+/*
+ * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to
+ * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0,
+ * respectively), but now are determined by compiling and running
+ * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1.
+ * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=...
+ * and -DNAN_WORD1=... values if necessary. This should still work.
+ * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.)
+ */
#ifdef IEEE_Arith
#ifdef IEEE_MC68k
#define _0 0
#define _1 1
+#ifndef NAN_WORD0
+#define NAN_WORD0 d_QNAN0
+#endif
+#ifndef NAN_WORD1
+#define NAN_WORD1 d_QNAN1
+#endif
#else
#define _0 1
#define _1 0
-#endif
-#else
-#undef INFNAN_CHECK
-#endif
-
-#ifdef INFNAN_CHECK
-
#ifndef NAN_WORD0
-#define NAN_WORD0 0x7ff80000
+#define NAN_WORD0 d_QNAN1
#endif
-
#ifndef NAN_WORD1
-#define NAN_WORD1 0
+#define NAN_WORD1 d_QNAN0
+#endif
+#endif
+#else
+#undef INFNAN_CHECK
#endif
-#endif /* INFNAN_CHECK */
#undef SI
#ifdef Sudden_Underflow