mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-11-29 06:59:59 +08:00
re PR fortran/47642 (real(kind=16) - libquadmath - segfault on amd64 FreeBSD)
PR fortran/47642 * libquadmath.texi (quadmath_snprintf): Document. (quadmath_flt128tostr): Remove. * Makefile.am (libquadmath_la_SOURCES): Add printf/*.c. Remove quadmath_io.c, gdtoa/gdtoa.c, gdtoa/g__fmt.c, gdtoa/g_Qfmt.c, gdtoa/dmisc.c and gdtoa/ulp.c. * quadmath.h (quadmath_snprintf): New prototype. (quadmath_flt128tostr): Remove. * quadmath_weak.h (quadmath_snprintf): Add. (quadmath_flt128tostr): Remove. * configure.ac: New AC_CHECK_HEADERS headers: langinfo.h, wchar.h, wctype.h, limits.h, ctype.h, printf.h, errno.h. (AC_USE_SYSTEM_EXTENSIONS): Add. (HAVE_HIDDEN_VISIBILITY, HAVE_PRINTF_HOOKS, USE_LOCALE_SUPPORT, USE_I18N_NUMBER_H): New checks. * quadmath.map (QUADMATH_1.0): Add quadmath_snprintf. Remove quadmath_flt128tostr. * printf/printf_fphex.c: New file. * printf/_itowa.h: New file. * printf/mul_n.c: New file. * printf/quadmath-printf.h: New file. * printf/submul_1.c: New file. * printf/quadmath-printf.c: New file. * printf/gmp-impl.h: New file. * printf/lshift.c: New file. * printf/fpioconst.h: New file. * printf/add_n.c: New file. * printf/cmp.c: New file. * printf/sub_n.c: New file. * printf/mul.c: New file. * printf/divrem.c: New file. * printf/addmul_1.c: New file. * printf/printf_fp.c: New file. * printf/_itoa.h: New file. * printf/fpioconst.c: New file. * printf/_i18n_number.h: New file. * printf/flt1282mpn.c: New file. * printf/rshift.c: New file. * printf/mul_1.c: New file. * quadmath_io.c: Removed. * gdtoa/gdtoa.c: Removed. * gdtoa/g__fmt.c: Removed. * gdtoa/g_Qfmt.c: Removed. * gdtoa/dmisc.c: Removed. * gdtoa/ulp.c: Removed. * config.h.in: Regenerated. * configure: Regenerated. * Makefile.in: Regenerated. * io/write_float.def (DTOAQ): Use quadmath_snprintf instead of quadmath_flt128tostr. * io/transfer128.c (tmp2): Initialize to quadmath_snprintf instead of quadmath_flt128tostr. From-SVN: r170135
This commit is contained in:
parent
944f4bb398
commit
1d92226be3
@ -1,3 +1,11 @@
|
||||
2011-02-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR fortran/47642
|
||||
* io/write_float.def (DTOAQ): Use quadmath_snprintf instead of
|
||||
quadmath_flt128tostr.
|
||||
* io/transfer128.c (tmp2): Initialize to quadmath_snprintf instead
|
||||
of quadmath_flt128tostr.
|
||||
|
||||
2011-02-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* Makefile.in: Regenerate.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010
|
||||
/* Copyright (C) 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Fortran runtime library (libgfortran).
|
||||
@ -62,12 +62,12 @@ export_proto(transfer_complex128_write);
|
||||
|
||||
|
||||
/* Make sure that libquadmath is pulled in. The functions strtoflt128
|
||||
and quadmath_flt128tostr are weakly referrenced in convert_real and
|
||||
and quadmath_snprintf are weakly referrenced in convert_real and
|
||||
write_float; the pointer assignment with USED attribute make sure
|
||||
that there is a non-weakref dependence if the quadmath functions
|
||||
are used. That avoids segfault when libquadmath is statically linked. */
|
||||
static void __attribute__((used)) *tmp1 = strtoflt128;
|
||||
static void __attribute__((used)) *tmp2 = quadmath_flt128tostr;
|
||||
static void __attribute__((used)) *tmp2 = quadmath_snprintf;
|
||||
|
||||
void
|
||||
transfer_real128 (st_parameter_dt *dtp, void *p, int kind)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Andy Vaught
|
||||
Write float code factoring to this file by Jerry DeLisle
|
||||
F2003 I/O support contributed by Jerry DeLisle
|
||||
@ -1000,7 +1000,9 @@ sprintf (buffer, "%+-#" STR(MIN_FIELD_WIDTH) ".*" \
|
||||
|
||||
#if defined(GFC_REAL_16_IS_FLOAT128)
|
||||
#define DTOAQ \
|
||||
__qmath_(quadmath_flt128tostr) (buffer, size, ndigits - 1, tmp);
|
||||
__qmath_(quadmath_snprintf) (buffer, sizeof buffer, \
|
||||
"%+-#" STR(MIN_FIELD_WIDTH) ".*" \
|
||||
"Qe", ndigits - 1, tmp);
|
||||
#endif
|
||||
|
||||
#define WRITE_FLOAT(x,y)\
|
||||
|
@ -1,3 +1,54 @@
|
||||
2011-02-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR fortran/47642
|
||||
* libquadmath.texi (quadmath_snprintf): Document.
|
||||
(quadmath_flt128tostr): Remove.
|
||||
* Makefile.am (libquadmath_la_SOURCES): Add printf/*.c.
|
||||
Remove quadmath_io.c, gdtoa/gdtoa.c, gdtoa/g__fmt.c,
|
||||
gdtoa/g_Qfmt.c, gdtoa/dmisc.c and gdtoa/ulp.c.
|
||||
* quadmath.h (quadmath_snprintf): New prototype.
|
||||
(quadmath_flt128tostr): Remove.
|
||||
* quadmath_weak.h (quadmath_snprintf): Add.
|
||||
(quadmath_flt128tostr): Remove.
|
||||
* configure.ac: New AC_CHECK_HEADERS headers: langinfo.h, wchar.h,
|
||||
wctype.h, limits.h, ctype.h, printf.h, errno.h.
|
||||
(AC_USE_SYSTEM_EXTENSIONS): Add.
|
||||
(HAVE_HIDDEN_VISIBILITY, HAVE_PRINTF_HOOKS,
|
||||
USE_LOCALE_SUPPORT, USE_I18N_NUMBER_H): New checks.
|
||||
* quadmath.map (QUADMATH_1.0): Add quadmath_snprintf. Remove
|
||||
quadmath_flt128tostr.
|
||||
* printf/printf_fphex.c: New file.
|
||||
* printf/_itowa.h: New file.
|
||||
* printf/mul_n.c: New file.
|
||||
* printf/quadmath-printf.h: New file.
|
||||
* printf/submul_1.c: New file.
|
||||
* printf/quadmath-printf.c: New file.
|
||||
* printf/gmp-impl.h: New file.
|
||||
* printf/lshift.c: New file.
|
||||
* printf/fpioconst.h: New file.
|
||||
* printf/add_n.c: New file.
|
||||
* printf/cmp.c: New file.
|
||||
* printf/sub_n.c: New file.
|
||||
* printf/mul.c: New file.
|
||||
* printf/divrem.c: New file.
|
||||
* printf/addmul_1.c: New file.
|
||||
* printf/printf_fp.c: New file.
|
||||
* printf/_itoa.h: New file.
|
||||
* printf/fpioconst.c: New file.
|
||||
* printf/_i18n_number.h: New file.
|
||||
* printf/flt1282mpn.c: New file.
|
||||
* printf/rshift.c: New file.
|
||||
* printf/mul_1.c: New file.
|
||||
* quadmath_io.c: Removed.
|
||||
* gdtoa/gdtoa.c: Removed.
|
||||
* gdtoa/g__fmt.c: Removed.
|
||||
* gdtoa/g_Qfmt.c: Removed.
|
||||
* gdtoa/dmisc.c: Removed.
|
||||
* gdtoa/ulp.c: Removed.
|
||||
* config.h.in: Regenerated.
|
||||
* configure: Regenerated.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
2011-02-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
|
||||
|
||||
* Makefile.in: Regenerate.
|
||||
|
@ -45,10 +45,9 @@ libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
|
||||
libquadmath_la_SOURCES = \
|
||||
gdtoa/arith.h gdtoa/gdtoa_fltrnds.h gdtoa/gd_qnan.h gdtoa/gdtoaimp.h \
|
||||
gdtoa/gdtoa.h quadmath-imp.h \
|
||||
gdtoa/dmisc.c gdtoa/gdtoa.c gdtoa/hd_init.c gdtoa/smisc.c gdtoa/sum.c \
|
||||
gdtoa/g_Qfmt.c gdtoa/gethex.c gdtoa/hexnan.c gdtoa/strtodg.c \
|
||||
gdtoa/ulp.c gdtoa/g__fmt.c gdtoa/gmisc.c gdtoa/misc.c gdtoa/strtopQ.c \
|
||||
quadmath_io.c \
|
||||
gdtoa/hd_init.c gdtoa/smisc.c gdtoa/sum.c \
|
||||
gdtoa/gethex.c gdtoa/hexnan.c gdtoa/strtodg.c \
|
||||
gdtoa/gmisc.c gdtoa/misc.c gdtoa/strtopQ.c \
|
||||
math/acoshq.c math/fmodq.c math/acosq.c math/frexpq.c \
|
||||
math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \
|
||||
math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \
|
||||
@ -65,7 +64,11 @@ libquadmath_la_SOURCES = \
|
||||
math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \
|
||||
math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \
|
||||
math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \
|
||||
math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c
|
||||
math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
|
||||
printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
|
||||
printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
|
||||
printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
|
||||
printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c
|
||||
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
|
@ -87,14 +87,11 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(infodir)" \
|
||||
"$(DESTDIR)$(libsubincludedir)"
|
||||
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
|
||||
am__dirstamp = $(am__leading_dot)dirstamp
|
||||
@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_OBJECTS = gdtoa/dmisc.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gdtoa.lo gdtoa/hd_init.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@am_libquadmath_la_OBJECTS = gdtoa/hd_init.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/smisc.lo gdtoa/sum.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/g_Qfmt.lo gdtoa/gethex.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/hexnan.lo gdtoa/strtodg.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/ulp.lo gdtoa/g__fmt.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gmisc.lo gdtoa/misc.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/strtopQ.lo quadmath_io.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gethex.lo gdtoa/hexnan.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/strtodg.lo gdtoa/gmisc.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/misc.lo gdtoa/strtopQ.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/acoshq.lo math/fmodq.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/acosq.lo math/frexpq.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.lo math/asinhq.lo \
|
||||
@ -133,7 +130,16 @@ am__dirstamp = $(am__leading_dot)dirstamp
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/fminq.lo math/ilogbq.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/llrintq.lo math/log2q.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/lrintq.lo math/nearbyintq.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/remquoq.lo
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/remquoq.lo printf/addmul_1.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/add_n.lo printf/cmp.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/divrem.lo printf/flt1282mpn.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/fpioconst.lo printf/lshift.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/mul_1.lo printf/mul_n.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/mul.lo printf/printf_fphex.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/printf_fp.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/rshift.lo printf/submul_1.lo \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/sub_n.lo
|
||||
libquadmath_la_OBJECTS = $(am_libquadmath_la_OBJECTS)
|
||||
libquadmath_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -319,10 +325,9 @@ AUTOMAKE_OPTIONS = 1.8 foreign
|
||||
@BUILD_LIBQUADMATH_TRUE@libquadmath_la_SOURCES = \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/arith.h gdtoa/gdtoa_fltrnds.h gdtoa/gd_qnan.h gdtoa/gdtoaimp.h \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gdtoa.h quadmath-imp.h \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/dmisc.c gdtoa/gdtoa.c gdtoa/hd_init.c gdtoa/smisc.c gdtoa/sum.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/g_Qfmt.c gdtoa/gethex.c gdtoa/hexnan.c gdtoa/strtodg.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/ulp.c gdtoa/g__fmt.c gdtoa/gmisc.c gdtoa/misc.c gdtoa/strtopQ.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ quadmath_io.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/hd_init.c gdtoa/smisc.c gdtoa/sum.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gethex.c gdtoa/hexnan.c gdtoa/strtodg.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ gdtoa/gmisc.c gdtoa/misc.c gdtoa/strtopQ.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/acoshq.c math/fmodq.c math/acosq.c math/frexpq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/rem_pio2q.c math/asinhq.c math/hypotq.c math/remainderq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/asinq.c math/rintq.c math/atan2q.c math/isinfq.c \
|
||||
@ -339,7 +344,11 @@ AUTOMAKE_OPTIONS = 1.8 foreign
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/cacoshq.c math/cacosq.c math/casinhq.c math/casinq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/catanhq.c math/catanq.c math/cimagq.c math/conjq.c math/cprojq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/crealq.c math/fdimq.c math/fmaxq.c math/fminq.c math/ilogbq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c
|
||||
@BUILD_LIBQUADMATH_TRUE@ math/llrintq.c math/log2q.c math/lrintq.c math/nearbyintq.c math/remquoq.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/addmul_1.c printf/add_n.c printf/cmp.c printf/divrem.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/flt1282mpn.c printf/fpioconst.c printf/lshift.c printf/mul_1.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/mul_n.c printf/mul.c printf/printf_fphex.c printf/printf_fp.c \
|
||||
@BUILD_LIBQUADMATH_TRUE@ printf/quadmath-printf.c printf/rshift.c printf/submul_1.c printf/sub_n.c
|
||||
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
@ -498,19 +507,14 @@ gdtoa/$(am__dirstamp):
|
||||
gdtoa/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) gdtoa/$(DEPDIR)
|
||||
@: > gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/dmisc.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/gdtoa.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/hd_init.lo: gdtoa/$(am__dirstamp) \
|
||||
gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/smisc.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/sum.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/g_Qfmt.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/gethex.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/hexnan.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/strtodg.lo: gdtoa/$(am__dirstamp) \
|
||||
gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/ulp.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/g__fmt.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/gmisc.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/misc.lo: gdtoa/$(am__dirstamp) gdtoa/$(DEPDIR)/$(am__dirstamp)
|
||||
gdtoa/strtopQ.lo: gdtoa/$(am__dirstamp) \
|
||||
@ -605,19 +609,47 @@ math/lrintq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
|
||||
math/nearbyintq.lo: math/$(am__dirstamp) \
|
||||
math/$(DEPDIR)/$(am__dirstamp)
|
||||
math/remquoq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/$(am__dirstamp):
|
||||
@$(MKDIR_P) printf
|
||||
@: > printf/$(am__dirstamp)
|
||||
printf/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) printf/$(DEPDIR)
|
||||
@: > printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/addmul_1.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/add_n.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/cmp.lo: printf/$(am__dirstamp) printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/divrem.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/flt1282mpn.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/fpioconst.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/lshift.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/mul_1.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/mul_n.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/mul.lo: printf/$(am__dirstamp) printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/printf_fphex.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/printf_fp.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/quadmath-printf.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/rshift.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/submul_1.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
printf/sub_n.lo: printf/$(am__dirstamp) \
|
||||
printf/$(DEPDIR)/$(am__dirstamp)
|
||||
libquadmath.la: $(libquadmath_la_OBJECTS) $(libquadmath_la_DEPENDENCIES)
|
||||
$(libquadmath_la_LINK) $(am_libquadmath_la_rpath) $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
-rm -f gdtoa/dmisc.$(OBJEXT)
|
||||
-rm -f gdtoa/dmisc.lo
|
||||
-rm -f gdtoa/g_Qfmt.$(OBJEXT)
|
||||
-rm -f gdtoa/g_Qfmt.lo
|
||||
-rm -f gdtoa/g__fmt.$(OBJEXT)
|
||||
-rm -f gdtoa/g__fmt.lo
|
||||
-rm -f gdtoa/gdtoa.$(OBJEXT)
|
||||
-rm -f gdtoa/gdtoa.lo
|
||||
-rm -f gdtoa/gethex.$(OBJEXT)
|
||||
-rm -f gdtoa/gethex.lo
|
||||
-rm -f gdtoa/gmisc.$(OBJEXT)
|
||||
@ -636,8 +668,6 @@ mostlyclean-compile:
|
||||
-rm -f gdtoa/strtopQ.lo
|
||||
-rm -f gdtoa/sum.$(OBJEXT)
|
||||
-rm -f gdtoa/sum.lo
|
||||
-rm -f gdtoa/ulp.$(OBJEXT)
|
||||
-rm -f gdtoa/ulp.lo
|
||||
-rm -f math/acoshq.$(OBJEXT)
|
||||
-rm -f math/acoshq.lo
|
||||
-rm -f math/acosq.$(OBJEXT)
|
||||
@ -792,15 +822,42 @@ mostlyclean-compile:
|
||||
-rm -f math/tgammaq.lo
|
||||
-rm -f math/truncq.$(OBJEXT)
|
||||
-rm -f math/truncq.lo
|
||||
-rm -f printf/add_n.$(OBJEXT)
|
||||
-rm -f printf/add_n.lo
|
||||
-rm -f printf/addmul_1.$(OBJEXT)
|
||||
-rm -f printf/addmul_1.lo
|
||||
-rm -f printf/cmp.$(OBJEXT)
|
||||
-rm -f printf/cmp.lo
|
||||
-rm -f printf/divrem.$(OBJEXT)
|
||||
-rm -f printf/divrem.lo
|
||||
-rm -f printf/flt1282mpn.$(OBJEXT)
|
||||
-rm -f printf/flt1282mpn.lo
|
||||
-rm -f printf/fpioconst.$(OBJEXT)
|
||||
-rm -f printf/fpioconst.lo
|
||||
-rm -f printf/lshift.$(OBJEXT)
|
||||
-rm -f printf/lshift.lo
|
||||
-rm -f printf/mul.$(OBJEXT)
|
||||
-rm -f printf/mul.lo
|
||||
-rm -f printf/mul_1.$(OBJEXT)
|
||||
-rm -f printf/mul_1.lo
|
||||
-rm -f printf/mul_n.$(OBJEXT)
|
||||
-rm -f printf/mul_n.lo
|
||||
-rm -f printf/printf_fp.$(OBJEXT)
|
||||
-rm -f printf/printf_fp.lo
|
||||
-rm -f printf/printf_fphex.$(OBJEXT)
|
||||
-rm -f printf/printf_fphex.lo
|
||||
-rm -f printf/quadmath-printf.$(OBJEXT)
|
||||
-rm -f printf/quadmath-printf.lo
|
||||
-rm -f printf/rshift.$(OBJEXT)
|
||||
-rm -f printf/rshift.lo
|
||||
-rm -f printf/sub_n.$(OBJEXT)
|
||||
-rm -f printf/sub_n.lo
|
||||
-rm -f printf/submul_1.$(OBJEXT)
|
||||
-rm -f printf/submul_1.lo
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quadmath_io.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/dmisc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/g_Qfmt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/g__fmt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/gdtoa.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/gethex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/gmisc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/hd_init.Plo@am__quote@
|
||||
@ -810,7 +867,6 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/strtodg.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/strtopQ.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/sum.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@gdtoa/$(DEPDIR)/ulp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/acoshq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/acosq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/asinhq.Plo@am__quote@
|
||||
@ -888,6 +944,22 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tanq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/tgammaq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/truncq.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/add_n.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/addmul_1.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/cmp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/divrem.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/flt1282mpn.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/fpioconst.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/lshift.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/mul.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/mul_1.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/mul_n.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/printf_fp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/printf_fphex.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/quadmath-printf.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/rshift.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/sub_n.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@printf/$(DEPDIR)/submul_1.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
@ -920,6 +992,7 @@ clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
-rm -rf gdtoa/.libs gdtoa/_libs
|
||||
-rm -rf math/.libs math/_libs
|
||||
-rm -rf printf/.libs printf/_libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
@ -1170,6 +1243,8 @@ distclean-generic:
|
||||
-rm -f gdtoa/$(am__dirstamp)
|
||||
-rm -f math/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f math/$(am__dirstamp)
|
||||
-rm -f printf/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f printf/$(am__dirstamp)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@ -1182,7 +1257,7 @@ clean-am: clean-aminfo clean-generic clean-libtool \
|
||||
|
||||
distclean: distclean-am distclean-multi
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf ./$(DEPDIR) gdtoa/$(DEPDIR) math/$(DEPDIR)
|
||||
-rm -rf gdtoa/$(DEPDIR) math/$(DEPDIR) printf/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
@ -1306,7 +1381,7 @@ installcheck-am:
|
||||
maintainer-clean: maintainer-clean-am maintainer-clean-multi
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf ./$(DEPDIR) gdtoa/$(DEPDIR) math/$(DEPDIR)
|
||||
-rm -rf gdtoa/$(DEPDIR) math/$(DEPDIR) printf/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-aminfo \
|
||||
maintainer-clean-generic
|
||||
|
@ -3,9 +3,15 @@
|
||||
/* libm includes cbrtl */
|
||||
#undef HAVE_CBRTL
|
||||
|
||||
/* Define to 1 if you have the <ctype.h> header file. */
|
||||
#undef HAVE_CTYPE_H
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#undef HAVE_ERRNO_H
|
||||
|
||||
/* libm includes feholdexcept */
|
||||
#undef HAVE_FEHOLDEXCEPT
|
||||
|
||||
@ -24,12 +30,27 @@
|
||||
/* libm includes feupdateenv */
|
||||
#undef HAVE_FEUPDATEENV
|
||||
|
||||
/* __attribute__((visibility ("hidden"))) supported */
|
||||
#undef HAVE_HIDDEN_VISIBILITY
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <langinfo.h> header file. */
|
||||
#undef HAVE_LANGINFO_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <printf.h> header file. */
|
||||
#undef HAVE_PRINTF_H
|
||||
|
||||
/* GNU C Library stype printf hooks supported */
|
||||
#undef HAVE_PRINTF_HOOKS
|
||||
|
||||
/* libm includes sqrtl */
|
||||
#undef HAVE_SQRTL
|
||||
|
||||
@ -54,6 +75,12 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#undef HAVE_WCTYPE_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
@ -85,5 +112,43 @@
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* whether i18n number rewriting can be supported */
|
||||
#undef USE_I18N_NUMBER_H
|
||||
|
||||
/* whether nl_langinfo is sufficiently supported */
|
||||
#undef USE_LOCALE_SUPPORT
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
1713
libquadmath/configure
vendored
1713
libquadmath/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -42,6 +42,8 @@ AC_MSG_RESULT($version_specific_libs)
|
||||
|
||||
GCC_NO_EXECUTABLES
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
# See if makeinfo has been installed and is modern enough
|
||||
# that we can use it.
|
||||
ACX_CHECK_PROG_VER([MAKEINFO], [makeinfo], [--version],
|
||||
@ -110,7 +112,7 @@ esac
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
|
||||
AC_CHECK_HEADERS(fenv.h)
|
||||
AC_CHECK_HEADERS(fenv.h langinfo.h wchar.h wctype.h limits.h ctype.h printf.h errno.h)
|
||||
|
||||
# If available, sqrtl and cbrtl speed up the calculation -
|
||||
# but they are not required
|
||||
@ -146,6 +148,16 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for hidden visibility (copied from libssp).
|
||||
AC_MSG_CHECKING([whether hidden visibility is supported])
|
||||
AC_TRY_COMPILE([
|
||||
void __attribute__((visibility ("hidden"))) bar (void) {}],,
|
||||
[quadmath_hidden=yes],[quadmath_hidden=no])
|
||||
AC_MSG_RESULT($quadmath_hidden)
|
||||
if test x$quadmath_hidden = xyes; then
|
||||
AC_DEFINE([HAVE_HIDDEN_VISIBILITY],[1],[__attribute__((visibility ("hidden"))) supported])
|
||||
fi
|
||||
|
||||
# Check for symbol versioning (copied from libssp).
|
||||
AC_MSG_CHECKING([whether symbol versioning is supported])
|
||||
if test x$gcc_no_link = xyes; then
|
||||
@ -213,6 +225,75 @@ AC_CACHE_CHECK([whether __float128 is supported], [libquad_cv_have_float128],
|
||||
])])
|
||||
AM_CONDITIONAL(BUILD_LIBQUADMATH, [test "x$libquad_cv_have_float128" = xyes])
|
||||
|
||||
# Check for printf hook support.
|
||||
AC_MSG_CHECKING([whether printf hooks are supported])
|
||||
AC_TRY_COMPILE([
|
||||
#include <printf.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
extern void flt128_va (void *, va_list *);
|
||||
extern int flt128_ais (const struct printf_info *, size_t, int *, int *);
|
||||
extern int flt128_printf_fp (FILE *, const struct printf_info *, const void *const *);
|
||||
],[
|
||||
int pa_flt128 = register_printf_type (flt128_va);
|
||||
int mod_Q = register_printf_modifier (L"Q");
|
||||
int res = register_printf_specifier ('f', flt128_printf_fp, flt128_ais);
|
||||
],
|
||||
[quadmath_printf_hooks=yes],[quadmath_printf_hooks=no])
|
||||
AC_MSG_RESULT($quadmath_printf_hooks)
|
||||
if test x$quadmath_printf_hooks = xyes; then
|
||||
AC_DEFINE([HAVE_PRINTF_HOOKS],[1],[GNU C Library stype printf hooks supported])
|
||||
fi
|
||||
|
||||
# Check for whether locale support for quadmath_snprintf or Q printf hooks
|
||||
# should be provided.
|
||||
AC_MSG_CHECKING([whether locale support for quadmath_snprintf should be added])
|
||||
AC_TRY_COMPILE([#include <langinfo.h>],[
|
||||
const char *s;
|
||||
s = nl_langinfo (DECIMAL_POINT);
|
||||
s = nl_langinfo (MON_DECIMAL_POINT);
|
||||
s = nl_langinfo (GROUPING);
|
||||
s = nl_langinfo (MON_GROUPING);
|
||||
s = nl_langinfo (THOUSANDS_SEP);
|
||||
s = nl_langinfo (MON_THOUSANDS_SEP);
|
||||
s = nl_langinfo (_NL_NUMERIC_DECIMAL_POINT_WC);
|
||||
s = nl_langinfo (_NL_MONETARY_DECIMAL_POINT_WC);
|
||||
s = nl_langinfo (_NL_NUMERIC_THOUSANDS_SEP_WC);
|
||||
s = nl_langinfo (_NL_MONETARY_THOUSANDS_SEP_WC);
|
||||
s = nl_langinfo (_NL_CTYPE_MB_CUR_MAX);
|
||||
(void) s;
|
||||
],
|
||||
[quadmath_use_locale_support=yes],[quadmath_use_locale_support=no])
|
||||
AC_MSG_RESULT($quadmath_use_locale_support)
|
||||
if test x$quadmath_use_locale_support = xyes; then
|
||||
AC_DEFINE([USE_LOCALE_SUPPORT],[1],[whether nl_langinfo is sufficiently supported])
|
||||
fi
|
||||
|
||||
# Check for whether i18n number rewriting support for quadmath_snprintf
|
||||
# or Q printf hooks should be provided.
|
||||
AC_MSG_CHECKING([whether i18n number rewriting support for quadmath_snprintf should be added])
|
||||
AC_TRY_COMPILE([#include <langinfo.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>],[
|
||||
const char *s;
|
||||
char decimal[MB_LEN_MAX];
|
||||
wctrans_t map = wctrans ("to_outpunct");
|
||||
wint_t wdecimal = towctrans (L'.', map);
|
||||
mbstate_t state;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
wcrtomb (decimal, wdecimal, &state);
|
||||
s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB);
|
||||
s = nl_langinfo (_NL_CTYPE_OUTDIGIT0_WC);
|
||||
(void) s;
|
||||
],
|
||||
[quadmath_use_i18n_number_h=yes],[quadmath_use_i18n_number_h=no])
|
||||
AC_MSG_RESULT($quadmath_use_i18n_number_h)
|
||||
if test x$quadmath_use_i18n_number_h = xyes; then
|
||||
AC_DEFINE([USE_I18N_NUMBER_H],[1],[whether i18n number rewriting can be supported])
|
||||
fi
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
||||
if test ${multilib} = yes; then
|
||||
|
@ -1,216 +0,0 @@
|
||||
/****************************************************************
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1998 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
||||
* with " at " changed at "@" and " dot " changed to "."). */
|
||||
|
||||
#include "gdtoaimp.h"
|
||||
|
||||
#ifndef MULTIPLE_THREADS
|
||||
char *dtoa_result;
|
||||
#endif
|
||||
|
||||
char *
|
||||
#ifdef KR_headers
|
||||
rv_alloc(i) int i;
|
||||
#else
|
||||
rv_alloc(int i)
|
||||
#endif
|
||||
{
|
||||
int j, k, *r;
|
||||
|
||||
j = sizeof(ULong);
|
||||
for(k = 0;
|
||||
sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
|
||||
j <<= 1)
|
||||
k++;
|
||||
r = (int*)Balloc(k);
|
||||
*r = k;
|
||||
return
|
||||
#ifndef MULTIPLE_THREADS
|
||||
dtoa_result =
|
||||
#endif
|
||||
(char *)(r+1);
|
||||
}
|
||||
|
||||
char *
|
||||
#ifdef KR_headers
|
||||
nrv_alloc(s, rve, n) char *s, **rve; int n;
|
||||
#else
|
||||
nrv_alloc(char *s, char **rve, int n)
|
||||
#endif
|
||||
{
|
||||
char *rv, *t;
|
||||
|
||||
t = rv = rv_alloc(n);
|
||||
while((*t = *s++) !=0)
|
||||
t++;
|
||||
if (rve)
|
||||
*rve = t;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* freedtoa(s) must be used to free values s returned by dtoa
|
||||
* when MULTIPLE_THREADS is #defined. It should be used in all cases,
|
||||
* but for consistency with earlier versions of dtoa, it is optional
|
||||
* when MULTIPLE_THREADS is not defined.
|
||||
*/
|
||||
|
||||
void
|
||||
#ifdef KR_headers
|
||||
freedtoa(s) char *s;
|
||||
#else
|
||||
freedtoa(char *s)
|
||||
#endif
|
||||
{
|
||||
Bigint *b = (Bigint *)((int *)s - 1);
|
||||
b->maxwds = 1 << (b->k = *(int*)b);
|
||||
Bfree(b);
|
||||
#ifndef MULTIPLE_THREADS
|
||||
if (s == dtoa_result)
|
||||
dtoa_result = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
quorem
|
||||
#ifdef KR_headers
|
||||
(b, S) Bigint *b, *S;
|
||||
#else
|
||||
(Bigint *b, Bigint *S)
|
||||
#endif
|
||||
{
|
||||
int n;
|
||||
ULong *bx, *bxe, q, *sx, *sxe;
|
||||
#ifdef ULLong
|
||||
ULLong borrow, carry, y, ys;
|
||||
#else
|
||||
ULong borrow, carry, y, ys;
|
||||
#ifdef Pack_32
|
||||
ULong si, z, zs;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
n = S->wds;
|
||||
#ifdef DEBUG
|
||||
/*debug*/ if (b->wds > n)
|
||||
/*debug*/ Bug("oversize b in quorem");
|
||||
#endif
|
||||
if (b->wds < n)
|
||||
return 0;
|
||||
sx = S->x;
|
||||
sxe = sx + --n;
|
||||
bx = b->x;
|
||||
bxe = bx + n;
|
||||
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
|
||||
#ifdef DEBUG
|
||||
/*debug*/ if (q > 9)
|
||||
/*debug*/ Bug("oversized quotient in quorem");
|
||||
#endif
|
||||
if (q) {
|
||||
borrow = 0;
|
||||
carry = 0;
|
||||
do {
|
||||
#ifdef ULLong
|
||||
ys = *sx++ * (ULLong)q + carry;
|
||||
carry = ys >> 32;
|
||||
y = *bx - (ys & 0xffffffffUL) - borrow;
|
||||
borrow = y >> 32 & 1UL;
|
||||
*bx++ = y & 0xffffffffUL;
|
||||
#else
|
||||
#ifdef Pack_32
|
||||
si = *sx++;
|
||||
ys = (si & 0xffff) * q + carry;
|
||||
zs = (si >> 16) * q + (ys >> 16);
|
||||
carry = zs >> 16;
|
||||
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
|
||||
borrow = (y & 0x10000) >> 16;
|
||||
z = (*bx >> 16) - (zs & 0xffff) - borrow;
|
||||
borrow = (z & 0x10000) >> 16;
|
||||
Storeinc(bx, z, y);
|
||||
#else
|
||||
ys = *sx++ * q + carry;
|
||||
carry = ys >> 16;
|
||||
y = *bx - (ys & 0xffff) - borrow;
|
||||
borrow = (y & 0x10000) >> 16;
|
||||
*bx++ = y & 0xffff;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
while(sx <= sxe);
|
||||
if (!*bxe) {
|
||||
bx = b->x;
|
||||
while(--bxe > bx && !*bxe)
|
||||
--n;
|
||||
b->wds = n;
|
||||
}
|
||||
}
|
||||
if (cmp(b, S) >= 0) {
|
||||
q++;
|
||||
borrow = 0;
|
||||
carry = 0;
|
||||
bx = b->x;
|
||||
sx = S->x;
|
||||
do {
|
||||
#ifdef ULLong
|
||||
ys = *sx++ + carry;
|
||||
carry = ys >> 32;
|
||||
y = *bx - (ys & 0xffffffffUL) - borrow;
|
||||
borrow = y >> 32 & 1UL;
|
||||
*bx++ = y & 0xffffffffUL;
|
||||
#else
|
||||
#ifdef Pack_32
|
||||
si = *sx++;
|
||||
ys = (si & 0xffff) + carry;
|
||||
zs = (si >> 16) + (ys >> 16);
|
||||
carry = zs >> 16;
|
||||
y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
|
||||
borrow = (y & 0x10000) >> 16;
|
||||
z = (*bx >> 16) - (zs & 0xffff) - borrow;
|
||||
borrow = (z & 0x10000) >> 16;
|
||||
Storeinc(bx, z, y);
|
||||
#else
|
||||
ys = *sx++ + carry;
|
||||
carry = ys >> 16;
|
||||
y = *bx - (ys & 0xffff) - borrow;
|
||||
borrow = (y & 0x10000) >> 16;
|
||||
*bx++ = y & 0xffff;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
while(sx <= sxe);
|
||||
bx = b->x;
|
||||
bxe = bx + n;
|
||||
if (!*bxe) {
|
||||
while(--bxe > bx && !*bxe)
|
||||
--n;
|
||||
b->wds = n;
|
||||
}
|
||||
}
|
||||
return q;
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
/****************************************************************
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1998, 2000 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
||||
* with " at " changed at "@" and " dot " changed to "."). */
|
||||
|
||||
#include "gdtoaimp.h"
|
||||
|
||||
#undef _0
|
||||
#undef _1
|
||||
|
||||
/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */
|
||||
|
||||
#ifdef IEEE_MC68k
|
||||
#define _0 0
|
||||
#define _1 1
|
||||
#define _2 2
|
||||
#define _3 3
|
||||
#endif
|
||||
#ifdef IEEE_8087
|
||||
#define _0 3
|
||||
#define _1 2
|
||||
#define _2 1
|
||||
#define _3 0
|
||||
#endif
|
||||
|
||||
char*
|
||||
#ifdef KR_headers
|
||||
g_Qfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; size_t bufsize;
|
||||
#else
|
||||
g_Qfmt(char *buf, void *V, int ndig, size_t bufsize)
|
||||
#endif
|
||||
{
|
||||
static FPI fpi0 = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 };
|
||||
char *b, *s, *se;
|
||||
ULong bits[4], *L, sign;
|
||||
int decpt, ex, i, mode;
|
||||
#ifdef Honor_FLT_ROUNDS
|
||||
#include "gdtoa_fltrnds.h"
|
||||
#else
|
||||
#define fpi &fpi0
|
||||
#endif
|
||||
|
||||
if (ndig < 0)
|
||||
ndig = 0;
|
||||
if (bufsize < ndig + 10)
|
||||
return 0;
|
||||
|
||||
L = (ULong*)V;
|
||||
sign = L[_0] & 0x80000000L;
|
||||
bits[3] = L[_0] & 0xffff;
|
||||
bits[2] = L[_1];
|
||||
bits[1] = L[_2];
|
||||
bits[0] = L[_3];
|
||||
b = buf;
|
||||
if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) {
|
||||
if (ex == 0x7fff) {
|
||||
/* Infinity or NaN */
|
||||
if (bits[0] | bits[1] | bits[2] | bits[3])
|
||||
b = strcpy(b, "NaN");
|
||||
else {
|
||||
b = buf;
|
||||
if (sign)
|
||||
*b++ = '-';
|
||||
b = strcpy(b, "Infinity");
|
||||
}
|
||||
return b;
|
||||
}
|
||||
i = STRTOG_Normal;
|
||||
bits[3] |= 0x10000;
|
||||
}
|
||||
else if (bits[0] | bits[1] | bits[2] | bits[3]) {
|
||||
i = STRTOG_Denormal;
|
||||
ex = 1;
|
||||
}
|
||||
else {
|
||||
#ifndef IGNORE_ZERO_SIGN
|
||||
if (sign)
|
||||
*b++ = '-';
|
||||
#endif
|
||||
*b++ = '0';
|
||||
*b = 0;
|
||||
return b;
|
||||
}
|
||||
ex -= 0x3fff + 112;
|
||||
mode = 2;
|
||||
if (ndig <= 0) {
|
||||
if (bufsize < 48)
|
||||
return 0;
|
||||
mode = 0;
|
||||
}
|
||||
s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
|
||||
|
||||
// FXC -- modifications
|
||||
|
||||
|
||||
|
||||
return g__fmt(buf, s, se, decpt, sign, bufsize);
|
||||
// FXC -- end of modifications
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
/****************************************************************
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1998 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
||||
* with " at " changed at "@" and " dot " changed to "."). */
|
||||
|
||||
#include "gdtoaimp.h"
|
||||
|
||||
#ifdef USE_LOCALE
|
||||
#include "locale.h"
|
||||
#endif
|
||||
|
||||
char *
|
||||
#ifdef KR_headers
|
||||
g__fmt(b, s, se, decpt, sign, blen) char *b; char *s; char *se; int decpt; ULong sign; size_t blen;
|
||||
#else
|
||||
g__fmt(char *b, char *s, char *se, int decpt, ULong sign, size_t blen)
|
||||
#endif
|
||||
{
|
||||
int i, j, k;
|
||||
char *be, *s0;
|
||||
size_t len;
|
||||
#ifdef USE_LOCALE
|
||||
#ifdef NO_LOCALE_CACHE
|
||||
char *decimalpoint = localeconv()->decimal_point;
|
||||
size_t dlen = strlen(decimalpoint);
|
||||
#else
|
||||
char *decimalpoint;
|
||||
static char *decimalpoint_cache;
|
||||
static size_t dlen;
|
||||
if (!(s0 = decimalpoint_cache)) {
|
||||
s0 = localeconv()->decimal_point;
|
||||
dlen = strlen(s0);
|
||||
if ((decimalpoint_cache = (char*)MALLOC(strlen(s0) + 1))) {
|
||||
strcpy(decimalpoint_cache, s0);
|
||||
s0 = decimalpoint_cache;
|
||||
}
|
||||
}
|
||||
decimalpoint = s0;
|
||||
#endif
|
||||
#else
|
||||
#define dlen 0
|
||||
#endif
|
||||
s0 = s;
|
||||
len = (se-s) + dlen + 6; /* 6 = sign + e+dd + trailing null */
|
||||
if (blen < len)
|
||||
goto ret0;
|
||||
be = b + blen - 1;
|
||||
if (sign)
|
||||
*b++ = '-';
|
||||
if (decpt <= -4 || decpt > se - s + 5) {
|
||||
*b++ = *s++;
|
||||
if (*s) {
|
||||
#ifdef USE_LOCALE
|
||||
while((*b = *decimalpoint++))
|
||||
++b;
|
||||
#else
|
||||
*b++ = '.';
|
||||
#endif
|
||||
while((*b = *s++) !=0)
|
||||
b++;
|
||||
}
|
||||
*b++ = 'e';
|
||||
/* sprintf(b, "%+.2d", decpt - 1); */
|
||||
if (--decpt < 0) {
|
||||
*b++ = '-';
|
||||
decpt = -decpt;
|
||||
}
|
||||
else
|
||||
*b++ = '+';
|
||||
for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){}
|
||||
for(;;) {
|
||||
i = decpt / k;
|
||||
if (b >= be)
|
||||
goto ret0;
|
||||
*b++ = i + '0';
|
||||
if (--j <= 0)
|
||||
break;
|
||||
decpt -= i*k;
|
||||
decpt *= 10;
|
||||
}
|
||||
*b = 0;
|
||||
}
|
||||
else if (decpt <= 0) {
|
||||
#ifdef USE_LOCALE
|
||||
while((*b = *decimalpoint++))
|
||||
++b;
|
||||
#else
|
||||
*b++ = '.';
|
||||
#endif
|
||||
if (be < b - decpt + (se - s))
|
||||
goto ret0;
|
||||
for(; decpt < 0; decpt++)
|
||||
*b++ = '0';
|
||||
while((*b = *s++) != 0)
|
||||
b++;
|
||||
}
|
||||
else {
|
||||
while((*b = *s++) != 0) {
|
||||
b++;
|
||||
if (--decpt == 0 && *s) {
|
||||
#ifdef USE_LOCALE
|
||||
while(*b = *decimalpoint++)
|
||||
++b;
|
||||
#else
|
||||
*b++ = '.';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (b + decpt > be) {
|
||||
ret0:
|
||||
b = 0;
|
||||
goto ret;
|
||||
}
|
||||
for(; decpt > 0; decpt--)
|
||||
*b++ = '0';
|
||||
*b = 0;
|
||||
}
|
||||
ret:
|
||||
freedtoa(s0);
|
||||
return b;
|
||||
}
|
@ -1,745 +0,0 @@
|
||||
/****************************************************************
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1998, 1999 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
||||
* with " at " changed at "@" and " dot " changed to "."). */
|
||||
|
||||
#include "gdtoaimp.h"
|
||||
|
||||
static Bigint *
|
||||
#ifdef KR_headers
|
||||
bitstob(bits, nbits, bbits) ULong *bits; int nbits; int *bbits;
|
||||
#else
|
||||
bitstob(ULong *bits, int nbits, int *bbits)
|
||||
#endif
|
||||
{
|
||||
int i, k;
|
||||
Bigint *b;
|
||||
ULong *be, *x, *x0;
|
||||
|
||||
i = ULbits;
|
||||
k = 0;
|
||||
while(i < nbits) {
|
||||
i <<= 1;
|
||||
k++;
|
||||
}
|
||||
#ifndef Pack_32
|
||||
if (!k)
|
||||
k = 1;
|
||||
#endif
|
||||
b = Balloc(k);
|
||||
be = bits + ((nbits - 1) >> kshift);
|
||||
x = x0 = b->x;
|
||||
do {
|
||||
*x++ = *bits & ALL_ON;
|
||||
#ifdef Pack_16
|
||||
*x++ = (*bits >> 16) & ALL_ON;
|
||||
#endif
|
||||
} while(++bits <= be);
|
||||
i = x - x0;
|
||||
while(!x0[--i])
|
||||
if (!i) {
|
||||
b->wds = 0;
|
||||
*bbits = 0;
|
||||
goto ret;
|
||||
}
|
||||
b->wds = i + 1;
|
||||
*bbits = i*ULbits + 32 - hi0bits(b->x[i]);
|
||||
ret:
|
||||
return b;
|
||||
}
|
||||
|
||||
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
|
||||
*
|
||||
* Inspired by "How to Print Floating-Point Numbers Accurately" by
|
||||
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
|
||||
*
|
||||
* Modifications:
|
||||
* 1. Rather than iterating, we use a simple numeric overestimate
|
||||
* to determine k = floor(log10(d)). We scale relevant
|
||||
* quantities using O(log2(k)) rather than O(k) multiplications.
|
||||
* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
|
||||
* try to generate digits strictly left to right. Instead, we
|
||||
* compute with fewer bits and propagate the carry if necessary
|
||||
* when rounding the final digit up. This is often faster.
|
||||
* 3. Under the assumption that input will be rounded nearest,
|
||||
* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
|
||||
* That is, we allow equality in stopping tests when the
|
||||
* round-nearest rule will give the same floating-point value
|
||||
* as would satisfaction of the stopping test with strict
|
||||
* inequality.
|
||||
* 4. We remove common factors of powers of 2 from relevant
|
||||
* quantities.
|
||||
* 5. When converting floating-point integers less than 1e16,
|
||||
* we use floating-point arithmetic rather than resorting
|
||||
* to multiple-precision integers.
|
||||
* 6. When asked to produce fewer than 15 digits, we first try
|
||||
* to get by with floating-point arithmetic; we resort to
|
||||
* multiple-precision integer arithmetic only if we cannot
|
||||
* guarantee that the floating-point calculation has given
|
||||
* the correctly rounded result. For k requested digits and
|
||||
* "uniformly" distributed input, the probability is
|
||||
* something like 10^(k-15) that we must resort to the Long
|
||||
* calculation.
|
||||
*/
|
||||
|
||||
char *
|
||||
gdtoa
|
||||
#ifdef KR_headers
|
||||
(fpi, be, bits, kindp, mode, ndigits, decpt, rve)
|
||||
FPI *fpi; int be; ULong *bits;
|
||||
int *kindp, mode, ndigits, *decpt; char **rve;
|
||||
#else
|
||||
(FPI *fpi, int be, ULong *bits, int *kindp, int mode, int ndigits, int *decpt, char **rve)
|
||||
#endif
|
||||
{
|
||||
/* Arguments ndigits and decpt are similar to the second and third
|
||||
arguments of ecvt and fcvt; trailing zeros are suppressed from
|
||||
the returned string. If not null, *rve is set to point
|
||||
to the end of the return value. If d is +-Infinity or NaN,
|
||||
then *decpt is set to 9999.
|
||||
|
||||
mode:
|
||||
0 ==> shortest string that yields d when read in
|
||||
and rounded to nearest.
|
||||
1 ==> like 0, but with Steele & White stopping rule;
|
||||
e.g. with IEEE P754 arithmetic , mode 0 gives
|
||||
1e23 whereas mode 1 gives 9.999999999999999e22.
|
||||
2 ==> max(1,ndigits) significant digits. This gives a
|
||||
return value similar to that of ecvt, except
|
||||
that trailing zeros are suppressed.
|
||||
3 ==> through ndigits past the decimal point. This
|
||||
gives a return value similar to that from fcvt,
|
||||
except that trailing zeros are suppressed, and
|
||||
ndigits can be negative.
|
||||
4-9 should give the same return values as 2-3, i.e.,
|
||||
4 <= mode <= 9 ==> same return as mode
|
||||
2 + (mode & 1). These modes are mainly for
|
||||
debugging; often they run slower but sometimes
|
||||
faster than modes 2-3.
|
||||
4,5,8,9 ==> left-to-right digit generation.
|
||||
6-9 ==> don't try fast floating-point estimate
|
||||
(if applicable).
|
||||
|
||||
Values of mode other than 0-9 are treated as mode 0.
|
||||
|
||||
Sufficient space is allocated to the return value
|
||||
to hold the suppressed trailing zeros.
|
||||
*/
|
||||
|
||||
int bbits, b2, b5, be0, dig, i, ieps, ilim, ilim0, ilim1, inex;
|
||||
int j, j1, k, k0, k_check, kind, leftright, m2, m5, nbits;
|
||||
int rdir, s2, s5, spec_case, try_quick;
|
||||
Long L;
|
||||
Bigint *b, *b1, *delta, *mlo, *mhi, *mhi1, *S;
|
||||
double d2, ds;
|
||||
char *s, *s0;
|
||||
U d, eps;
|
||||
|
||||
#ifndef MULTIPLE_THREADS
|
||||
if (dtoa_result) {
|
||||
freedtoa(dtoa_result);
|
||||
dtoa_result = 0;
|
||||
}
|
||||
#endif
|
||||
inex = 0;
|
||||
kind = *kindp &= ~STRTOG_Inexact;
|
||||
switch(kind & STRTOG_Retmask) {
|
||||
case STRTOG_Zero:
|
||||
goto ret_zero;
|
||||
case STRTOG_Normal:
|
||||
case STRTOG_Denormal:
|
||||
break;
|
||||
case STRTOG_Infinite:
|
||||
*decpt = -32768;
|
||||
return nrv_alloc("Infinity", rve, 8);
|
||||
case STRTOG_NaN:
|
||||
*decpt = -32768;
|
||||
return nrv_alloc("NaN", rve, 3);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
b = bitstob(bits, nbits = fpi->nbits, &bbits);
|
||||
be0 = be;
|
||||
if ( (i = trailz(b)) !=0) {
|
||||
rshift(b, i);
|
||||
be += i;
|
||||
bbits -= i;
|
||||
}
|
||||
if (!b->wds) {
|
||||
Bfree(b);
|
||||
ret_zero:
|
||||
*decpt = 1;
|
||||
return nrv_alloc("0", rve, 1);
|
||||
}
|
||||
|
||||
dval(&d) = b2d(b, &i);
|
||||
i = be + bbits - 1;
|
||||
word0(&d) &= Frac_mask1;
|
||||
word0(&d) |= Exp_11;
|
||||
#ifdef IBM
|
||||
if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
|
||||
dval(&d) /= 1 << j;
|
||||
#endif
|
||||
|
||||
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
|
||||
* log10(x) = log(x) / log(10)
|
||||
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
|
||||
* log10(&d) = (i-Bias)*log(2)/log(10) + log10(d2)
|
||||
*
|
||||
* This suggests computing an approximation k to log10(&d) by
|
||||
*
|
||||
* k = (i - Bias)*0.301029995663981
|
||||
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
|
||||
*
|
||||
* We want k to be too large rather than too small.
|
||||
* The error in the first-order Taylor series approximation
|
||||
* is in our favor, so we just round up the constant enough
|
||||
* to compensate for any error in the multiplication of
|
||||
* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
|
||||
* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
|
||||
* adding 1e-13 to the constant term more than suffices.
|
||||
* Hence we adjust the constant term to 0.1760912590558.
|
||||
* (We could get a more accurate k by invoking log10,
|
||||
* but this is probably not worthwhile.)
|
||||
*/
|
||||
#ifdef IBM
|
||||
i <<= 2;
|
||||
i += j;
|
||||
#endif
|
||||
ds = (dval(&d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
|
||||
|
||||
/* correct assumption about exponent range */
|
||||
if ((j = i) < 0)
|
||||
j = -j;
|
||||
if ((j -= 1077) > 0)
|
||||
ds += j * 7e-17;
|
||||
|
||||
k = (int)ds;
|
||||
if (ds < 0. && ds != k)
|
||||
k--; /* want k = floor(ds) */
|
||||
k_check = 1;
|
||||
#ifdef IBM
|
||||
j = be + bbits - 1;
|
||||
if ( (j1 = j & 3) !=0)
|
||||
dval(&d) *= 1 << j1;
|
||||
word0(&d) += j << Exp_shift - 2 & Exp_mask;
|
||||
#else
|
||||
word0(&d) += (be + bbits - 1) << Exp_shift;
|
||||
#endif
|
||||
if (k >= 0 && k <= Ten_pmax) {
|
||||
if (dval(&d) < tens[k])
|
||||
k--;
|
||||
k_check = 0;
|
||||
}
|
||||
j = bbits - i - 1;
|
||||
if (j >= 0) {
|
||||
b2 = 0;
|
||||
s2 = j;
|
||||
}
|
||||
else {
|
||||
b2 = -j;
|
||||
s2 = 0;
|
||||
}
|
||||
if (k >= 0) {
|
||||
b5 = 0;
|
||||
s5 = k;
|
||||
s2 += k;
|
||||
}
|
||||
else {
|
||||
b2 -= k;
|
||||
b5 = -k;
|
||||
s5 = 0;
|
||||
}
|
||||
if (mode < 0 || mode > 9)
|
||||
mode = 0;
|
||||
try_quick = 1;
|
||||
if (mode > 5) {
|
||||
mode -= 4;
|
||||
try_quick = 0;
|
||||
}
|
||||
leftright = 1;
|
||||
ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
|
||||
/* silence erroneous "gcc -Wall" warning. */
|
||||
switch(mode) {
|
||||
case 0:
|
||||
case 1:
|
||||
i = (int)(nbits * .30103) + 3;
|
||||
ndigits = 0;
|
||||
break;
|
||||
case 2:
|
||||
leftright = 0;
|
||||
/* no break */
|
||||
case 4:
|
||||
if (ndigits <= 0)
|
||||
ndigits = 1;
|
||||
ilim = ilim1 = i = ndigits;
|
||||
break;
|
||||
case 3:
|
||||
leftright = 0;
|
||||
/* no break */
|
||||
case 5:
|
||||
i = ndigits + k + 1;
|
||||
ilim = i;
|
||||
ilim1 = i - 1;
|
||||
if (i <= 0)
|
||||
i = 1;
|
||||
}
|
||||
s = s0 = rv_alloc(i);
|
||||
|
||||
if ( (rdir = fpi->rounding - 1) !=0) {
|
||||
if (rdir < 0)
|
||||
rdir = 2;
|
||||
if (kind & STRTOG_Neg)
|
||||
rdir = 3 - rdir;
|
||||
}
|
||||
|
||||
/* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */
|
||||
|
||||
if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir
|
||||
#ifndef IMPRECISE_INEXACT
|
||||
&& k == 0
|
||||
#endif
|
||||
) {
|
||||
|
||||
/* Try to get by with floating-point arithmetic. */
|
||||
|
||||
i = 0;
|
||||
d2 = dval(&d);
|
||||
#ifdef IBM
|
||||
if ( (j = 11 - hi0bits(word0(&d) & Frac_mask)) !=0)
|
||||
dval(&d) /= 1 << j;
|
||||
#endif
|
||||
k0 = k;
|
||||
ilim0 = ilim;
|
||||
ieps = 2; /* conservative */
|
||||
if (k > 0) {
|
||||
ds = tens[k&0xf];
|
||||
j = k >> 4;
|
||||
if (j & Bletch) {
|
||||
/* prevent overflows */
|
||||
j &= Bletch - 1;
|
||||
dval(&d) /= bigtens[n_bigtens-1];
|
||||
ieps++;
|
||||
}
|
||||
for(; j; j >>= 1, i++)
|
||||
if (j & 1) {
|
||||
ieps++;
|
||||
ds *= bigtens[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
ds = 1.;
|
||||
if ( (j1 = -k) !=0) {
|
||||
dval(&d) *= tens[j1 & 0xf];
|
||||
for(j = j1 >> 4; j; j >>= 1, i++)
|
||||
if (j & 1) {
|
||||
ieps++;
|
||||
dval(&d) *= bigtens[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (k_check && dval(&d) < 1. && ilim > 0) {
|
||||
if (ilim1 <= 0)
|
||||
goto fast_failed;
|
||||
ilim = ilim1;
|
||||
k--;
|
||||
dval(&d) *= 10.;
|
||||
ieps++;
|
||||
}
|
||||
dval(&eps) = ieps*dval(&d) + 7.;
|
||||
word0(&eps) -= (P-1)*Exp_msk1;
|
||||
if (ilim == 0) {
|
||||
S = mhi = 0;
|
||||
dval(&d) -= 5.;
|
||||
if (dval(&d) > dval(&eps))
|
||||
goto one_digit;
|
||||
if (dval(&d) < -dval(&eps))
|
||||
goto no_digits;
|
||||
goto fast_failed;
|
||||
}
|
||||
#ifndef No_leftright
|
||||
if (leftright) {
|
||||
/* Use Steele & White method of only
|
||||
* generating digits needed.
|
||||
*/
|
||||
dval(&eps) = ds*0.5/tens[ilim-1] - dval(&eps);
|
||||
for(i = 0;;) {
|
||||
L = (Long)(dval(&d)/ds);
|
||||
dval(&d) -= L*ds;
|
||||
*s++ = '0' + (int)L;
|
||||
if (dval(&d) < dval(&eps)) {
|
||||
if (dval(&d))
|
||||
inex = STRTOG_Inexlo;
|
||||
goto ret1;
|
||||
}
|
||||
if (ds - dval(&d) < dval(&eps))
|
||||
goto bump_up;
|
||||
if (++i >= ilim)
|
||||
break;
|
||||
dval(&eps) *= 10.;
|
||||
dval(&d) *= 10.;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
/* Generate ilim digits, then fix them up. */
|
||||
dval(&eps) *= tens[ilim-1];
|
||||
for(i = 1;; i++, dval(&d) *= 10.) {
|
||||
if ( (L = (Long)(dval(&d)/ds)) !=0)
|
||||
dval(&d) -= L*ds;
|
||||
*s++ = '0' + (int)L;
|
||||
if (i == ilim) {
|
||||
ds *= 0.5;
|
||||
if (dval(&d) > ds + dval(&eps))
|
||||
goto bump_up;
|
||||
else if (dval(&d) < ds - dval(&eps)) {
|
||||
if (dval(&d))
|
||||
inex = STRTOG_Inexlo;
|
||||
goto clear_trailing0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifndef No_leftright
|
||||
}
|
||||
#endif
|
||||
fast_failed:
|
||||
s = s0;
|
||||
dval(&d) = d2;
|
||||
k = k0;
|
||||
ilim = ilim0;
|
||||
}
|
||||
|
||||
/* Do we have a "small" integer? */
|
||||
|
||||
if (be >= 0 && k <= Int_max) {
|
||||
/* Yes. */
|
||||
ds = tens[k];
|
||||
if (ndigits < 0 && ilim <= 0) {
|
||||
S = mhi = 0;
|
||||
if (ilim < 0 || dval(&d) <= 5*ds)
|
||||
goto no_digits;
|
||||
goto one_digit;
|
||||
}
|
||||
for(i = 1;; i++, dval(&d) *= 10.) {
|
||||
L = dval(&d) / ds;
|
||||
dval(&d) -= L*ds;
|
||||
#ifdef Check_FLT_ROUNDS
|
||||
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
|
||||
if (dval(&d) < 0) {
|
||||
L--;
|
||||
dval(&d) += ds;
|
||||
}
|
||||
#endif
|
||||
*s++ = '0' + (int)L;
|
||||
if (dval(&d) == 0.)
|
||||
break;
|
||||
if (i == ilim) {
|
||||
if (rdir) {
|
||||
if (rdir == 1)
|
||||
goto bump_up;
|
||||
inex = STRTOG_Inexlo;
|
||||
goto ret1;
|
||||
}
|
||||
dval(&d) += dval(&d);
|
||||
if (dval(&d) > ds || (dval(&d) == ds && L & 1)) {
|
||||
bump_up:
|
||||
inex = STRTOG_Inexhi;
|
||||
while(*--s == '9')
|
||||
if (s == s0) {
|
||||
k++;
|
||||
*s = '0';
|
||||
break;
|
||||
}
|
||||
++*s++;
|
||||
}
|
||||
else {
|
||||
inex = STRTOG_Inexlo;
|
||||
clear_trailing0:
|
||||
while(*--s == '0'){}
|
||||
++s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto ret1;
|
||||
}
|
||||
|
||||
m2 = b2;
|
||||
m5 = b5;
|
||||
mhi = mlo = 0;
|
||||
if (leftright) {
|
||||
if (mode < 2) {
|
||||
i = nbits - bbits;
|
||||
if (be - i++ < fpi->emin)
|
||||
/* denormal */
|
||||
i = be - fpi->emin + 1;
|
||||
}
|
||||
else {
|
||||
j = ilim - 1;
|
||||
if (m5 >= j)
|
||||
m5 -= j;
|
||||
else {
|
||||
s5 += j -= m5;
|
||||
b5 += j;
|
||||
m5 = 0;
|
||||
}
|
||||
if ((i = ilim) < 0) {
|
||||
m2 -= i;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
b2 += i;
|
||||
s2 += i;
|
||||
mhi = i2b(1);
|
||||
}
|
||||
if (m2 > 0 && s2 > 0) {
|
||||
i = m2 < s2 ? m2 : s2;
|
||||
b2 -= i;
|
||||
m2 -= i;
|
||||
s2 -= i;
|
||||
}
|
||||
if (b5 > 0) {
|
||||
if (leftright) {
|
||||
if (m5 > 0) {
|
||||
mhi = pow5mult(mhi, m5);
|
||||
b1 = mult(mhi, b);
|
||||
Bfree(b);
|
||||
b = b1;
|
||||
}
|
||||
if ( (j = b5 - m5) !=0)
|
||||
b = pow5mult(b, j);
|
||||
}
|
||||
else
|
||||
b = pow5mult(b, b5);
|
||||
}
|
||||
S = i2b(1);
|
||||
if (s5 > 0)
|
||||
S = pow5mult(S, s5);
|
||||
|
||||
/* Check for special case that d is a normalized power of 2. */
|
||||
|
||||
spec_case = 0;
|
||||
if (mode < 2) {
|
||||
if (bbits == 1 && be0 > fpi->emin + 1) {
|
||||
/* The special case */
|
||||
b2++;
|
||||
s2++;
|
||||
spec_case = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Arrange for convenient computation of quotients:
|
||||
* shift left if necessary so divisor has 4 leading 0 bits.
|
||||
*
|
||||
* Perhaps we should just compute leading 28 bits of S once
|
||||
* and for all and pass them and a shift to quorem, so it
|
||||
* can do shifts and ors to compute the numerator for q.
|
||||
*/
|
||||
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 += i) > 0)
|
||||
S = lshift(S, s2);
|
||||
if (k_check) {
|
||||
if (cmp(b,S) < 0) {
|
||||
k--;
|
||||
b = multadd(b, 10, 0); /* we botched the k estimate */
|
||||
if (leftright)
|
||||
mhi = multadd(mhi, 10, 0);
|
||||
ilim = ilim1;
|
||||
}
|
||||
}
|
||||
if (ilim <= 0 && mode > 2) {
|
||||
if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
|
||||
/* no digits, fcvt style */
|
||||
no_digits:
|
||||
k = -1 - ndigits;
|
||||
inex = STRTOG_Inexlo;
|
||||
goto ret;
|
||||
}
|
||||
one_digit:
|
||||
inex = STRTOG_Inexhi;
|
||||
*s++ = '1';
|
||||
k++;
|
||||
goto ret;
|
||||
}
|
||||
if (leftright) {
|
||||
if (m2 > 0)
|
||||
mhi = lshift(mhi, m2);
|
||||
|
||||
/* Compute mlo -- check for special case
|
||||
* that d is a normalized power of 2.
|
||||
*/
|
||||
|
||||
mlo = mhi;
|
||||
if (spec_case) {
|
||||
mhi = Balloc(mhi->k);
|
||||
Bcopy(mhi, mlo);
|
||||
mhi = lshift(mhi, 1);
|
||||
}
|
||||
|
||||
for(i = 1;;i++) {
|
||||
dig = quorem(b,S) + '0';
|
||||
/* Do we yet have the shortest decimal string
|
||||
* that will round to d?
|
||||
*/
|
||||
j = cmp(b, mlo);
|
||||
delta = diff(S, mhi);
|
||||
j1 = delta->sign ? 1 : cmp(b, delta);
|
||||
Bfree(delta);
|
||||
#ifndef ROUND_BIASED
|
||||
if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) {
|
||||
if (dig == '9')
|
||||
goto round_9_up;
|
||||
if (j <= 0) {
|
||||
if (b->wds > 1 || b->x[0])
|
||||
inex = STRTOG_Inexlo;
|
||||
}
|
||||
else {
|
||||
dig++;
|
||||
inex = STRTOG_Inexhi;
|
||||
}
|
||||
*s++ = dig;
|
||||
goto ret;
|
||||
}
|
||||
#endif
|
||||
if (j < 0 || (j == 0 && !mode
|
||||
#ifndef ROUND_BIASED
|
||||
&& !(bits[0] & 1)
|
||||
#endif
|
||||
)) {
|
||||
if (rdir && (b->wds > 1 || b->x[0])) {
|
||||
if (rdir == 2) {
|
||||
inex = STRTOG_Inexlo;
|
||||
goto accept;
|
||||
}
|
||||
while (cmp(S,mhi) > 0) {
|
||||
*s++ = dig;
|
||||
mhi1 = multadd(mhi, 10, 0);
|
||||
if (mlo == mhi)
|
||||
mlo = mhi1;
|
||||
mhi = mhi1;
|
||||
b = multadd(b, 10, 0);
|
||||
dig = quorem(b,S) + '0';
|
||||
}
|
||||
if (dig++ == '9')
|
||||
goto round_9_up;
|
||||
inex = STRTOG_Inexhi;
|
||||
goto accept;
|
||||
}
|
||||
if (j1 > 0) {
|
||||
b = lshift(b, 1);
|
||||
j1 = cmp(b, S);
|
||||
if ((j1 > 0 || (j1 == 0 && dig & 1))
|
||||
&& dig++ == '9')
|
||||
goto round_9_up;
|
||||
inex = STRTOG_Inexhi;
|
||||
}
|
||||
if (b->wds > 1 || b->x[0])
|
||||
inex = STRTOG_Inexlo;
|
||||
accept:
|
||||
*s++ = dig;
|
||||
goto ret;
|
||||
}
|
||||
if (j1 > 0 && rdir != 2) {
|
||||
if (dig == '9') { /* possible if i == 1 */
|
||||
round_9_up:
|
||||
*s++ = '9';
|
||||
inex = STRTOG_Inexhi;
|
||||
goto roundoff;
|
||||
}
|
||||
inex = STRTOG_Inexhi;
|
||||
*s++ = dig + 1;
|
||||
goto ret;
|
||||
}
|
||||
*s++ = dig;
|
||||
if (i == ilim)
|
||||
break;
|
||||
b = multadd(b, 10, 0);
|
||||
if (mlo == mhi)
|
||||
mlo = mhi = multadd(mhi, 10, 0);
|
||||
else {
|
||||
mlo = multadd(mlo, 10, 0);
|
||||
mhi = multadd(mhi, 10, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
for(i = 1;; i++) {
|
||||
*s++ = dig = quorem(b,S) + '0';
|
||||
if (i >= ilim)
|
||||
break;
|
||||
b = multadd(b, 10, 0);
|
||||
}
|
||||
|
||||
/* Round off last digit */
|
||||
|
||||
if (rdir) {
|
||||
if (rdir == 2 || (b->wds <= 1 && !b->x[0]))
|
||||
goto chopzeros;
|
||||
goto roundoff;
|
||||
}
|
||||
b = lshift(b, 1);
|
||||
j = cmp(b, S);
|
||||
if (j > 0 || (j == 0 && dig & 1)) {
|
||||
roundoff:
|
||||
inex = STRTOG_Inexhi;
|
||||
while(*--s == '9')
|
||||
if (s == s0) {
|
||||
k++;
|
||||
*s++ = '1';
|
||||
goto ret;
|
||||
}
|
||||
++*s++;
|
||||
}
|
||||
else {
|
||||
chopzeros:
|
||||
if (b->wds > 1 || b->x[0])
|
||||
inex = STRTOG_Inexlo;
|
||||
while(*--s == '0'){}
|
||||
++s;
|
||||
}
|
||||
ret:
|
||||
Bfree(S);
|
||||
if (mhi) {
|
||||
if (mlo && mlo != mhi)
|
||||
Bfree(mlo);
|
||||
Bfree(mhi);
|
||||
}
|
||||
ret1:
|
||||
Bfree(b);
|
||||
*s = 0;
|
||||
*decpt = k + 1;
|
||||
if (rve)
|
||||
*rve = s;
|
||||
*kindp |= inex;
|
||||
return s0;
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/****************************************************************
|
||||
|
||||
The author of this software is David M. Gay.
|
||||
|
||||
Copyright (C) 1998, 1999 by Lucent Technologies
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and
|
||||
its documentation for any purpose and without fee is hereby
|
||||
granted, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of Lucent or any of its entities
|
||||
not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior
|
||||
permission.
|
||||
|
||||
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
||||
****************************************************************/
|
||||
|
||||
/* Please send bug reports to David M. Gay (dmg at acm dot org,
|
||||
* with " at " changed at "@" and " dot " changed to "."). */
|
||||
|
||||
#include "gdtoaimp.h"
|
||||
|
||||
double
|
||||
ulp
|
||||
#ifdef KR_headers
|
||||
(x) U *x;
|
||||
#else
|
||||
(U *x)
|
||||
#endif
|
||||
{
|
||||
Long L;
|
||||
U a;
|
||||
|
||||
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
|
||||
#ifndef Sudden_Underflow
|
||||
if (L > 0) {
|
||||
#endif
|
||||
#ifdef IBM
|
||||
L |= Exp_msk1 >> 4;
|
||||
#endif
|
||||
word0(&a) = L;
|
||||
word1(&a) = 0;
|
||||
#ifndef Sudden_Underflow
|
||||
}
|
||||
else {
|
||||
L = -L >> Exp_shift;
|
||||
if (L < Exp_shift) {
|
||||
word0(&a) = 0x80000 >> L;
|
||||
word1(&a) = 0;
|
||||
}
|
||||
else {
|
||||
word0(&a) = 0;
|
||||
L -= Exp_shift;
|
||||
word1(&a) = L >= 31 ? 1 : 1 << (31 - L);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return dval(&a);
|
||||
}
|
@ -246,7 +246,7 @@ The following mathematical functions are available:
|
||||
|
||||
@menu
|
||||
* @code{strtoflt128}: strtoflt128, Convert from string
|
||||
* @code{quadmath_flt128tostr}: quadmath_flt128tostr, Convert to string
|
||||
* @code{quadmath_snprintf}: quadmath_snprintf, Convert to string
|
||||
@end menu
|
||||
|
||||
|
||||
@ -289,43 +289,73 @@ int main ()
|
||||
@end table
|
||||
|
||||
|
||||
@node quadmath_flt128tostr
|
||||
@section @code{quadmath_flt128tostr} --- Convert to string
|
||||
@node quadmath_snprintf
|
||||
@section @code{quadmath_snprintf} --- Convert to string
|
||||
|
||||
The function @code{quadmath_flt128tostr} converts a @code{__float128} floating-point
|
||||
number into a string.
|
||||
The function @code{quadmath_snprintf} converts a @code{__float128} floating-point
|
||||
number into a string. It is a specialized alternative to @code{snprintf}, where
|
||||
the format string is restricted to a single conversion specifier with @code{Q}
|
||||
modifier and conversion specifier @code{e}, @code{E}, @code{f}, @code{F}, @code{g},
|
||||
@code{G}, @code{a} or @code{A}, with no extra characters before or after the
|
||||
conversion specifier. The @code{%m$} or @code{*m$} style must not be used in
|
||||
the format.
|
||||
|
||||
@table @asis
|
||||
@item Syntax
|
||||
@code{void quadmath_flt128tostr (char *s, size_t size, size_t n, __float128 x)}
|
||||
@code{int quadmath_snprintf (char *s, size_t size, const char *format, ...)}
|
||||
|
||||
@item @emph{Arguments}:
|
||||
@multitable @columnfractions .15 .70
|
||||
@item @var{s} @tab output string
|
||||
@item @var{size} @tab byte size of the string, including tailing NUL
|
||||
@item @var{n} @tab number of digits after the decimal point
|
||||
@item @var{x} @tab the number to be converted
|
||||
@item @var{format} @tab conversion specifier string
|
||||
@end multitable
|
||||
|
||||
@item Example
|
||||
@smallexample
|
||||
#include <quadmath.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main ()
|
||||
@{
|
||||
__float128 r;
|
||||
char str[200];
|
||||
int prec = 20;
|
||||
int width = 46;
|
||||
char buf[128];
|
||||
|
||||
r = 2.0q;
|
||||
r = sqrtq(r);
|
||||
quadmath_flt128tostr (str, sizeof (str), 20, r);
|
||||
printf("%s\n", str);
|
||||
/* Prints: +1.41421356237309504880e+00 */
|
||||
r = sqrtq (r);
|
||||
int n = quadmath_snprintf (buf, sizeof buf, "%+-#*.20Qe", width, r);
|
||||
if ((size_t) n < sizeof buf)
|
||||
printf ("%s\n", buf);
|
||||
/* Prints: +1.41421356237309504880e+00 */
|
||||
quadmath_snprintf (buf, sizeof buf, "%Qa", r);
|
||||
if ((size_t) n < sizeof buf)
|
||||
printf ("%s\n", buf);
|
||||
/* Prints: 0x1.6a09e667f3bcc908b2fb1366ea96p+0 */
|
||||
n = quadmath_snprintf (NULL, 0, "%+-#46.*Qe", prec, r);
|
||||
if (n > -1)
|
||||
@{
|
||||
char *str = malloc (n + 1);
|
||||
if (str)
|
||||
@{
|
||||
quadmath_snprintf (str, n + 1, "%+-#46.*Qe", prec, r);
|
||||
printf ("%s\n", str);
|
||||
/* Prints: +1.41421356237309504880e+00 */
|
||||
@}
|
||||
free (str);
|
||||
@}
|
||||
return 0;
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
@end table
|
||||
|
||||
On some targets when supported by the C library hooks are installed
|
||||
for @code{printf} family of functions, so that @code{printf ("%Qe", 1.2Q);}
|
||||
etc.@: works too.
|
||||
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c GNU Free Documentation License
|
||||
|
139
libquadmath/printf/_i18n_number.h
Normal file
139
libquadmath/printf/_i18n_number.h
Normal file
@ -0,0 +1,139 @@
|
||||
/* Copyright (C) 2000, 2004, 2008 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@gnu.org>, 2000.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* Look up the value of the next multibyte character and return its numerical
|
||||
value if it is one of the digits known in the locale. If *DECIDED is
|
||||
-1 this means it is not yet decided which form it is and we have to
|
||||
search through all available digits. Otherwise we know which script
|
||||
the digits are from. */
|
||||
static inline char *
|
||||
outdigit_value (char *s, int n)
|
||||
{
|
||||
const char *outdigit;
|
||||
size_t dlen;
|
||||
|
||||
assert (0 <= n && n <= 9);
|
||||
outdigit = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB + n);
|
||||
dlen = strlen (outdigit);
|
||||
|
||||
s -= dlen;
|
||||
while (dlen-- > 0)
|
||||
s[dlen] = outdigit[dlen];
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Look up the value of the next multibyte character and return its numerical
|
||||
value if it is one of the digits known in the locale. If *DECIDED is
|
||||
-1 this means it is not yet decided which form it is and we have to
|
||||
search through all available digits. Otherwise we know which script
|
||||
the digits are from. */
|
||||
static inline wchar_t
|
||||
outdigitwc_value (int n)
|
||||
{
|
||||
assert (0 <= n && n <= 9);
|
||||
|
||||
return nl_langinfo_wc (_NL_CTYPE_OUTDIGIT0_WC + n);
|
||||
}
|
||||
|
||||
static char *
|
||||
_i18n_number_rewrite (char *w, char *rear_ptr, char *end)
|
||||
{
|
||||
char decimal[MB_LEN_MAX + 1];
|
||||
char thousands[MB_LEN_MAX + 1];
|
||||
|
||||
/* "to_outpunct" is a map from ASCII decimal point and thousands-sep
|
||||
to their equivalent in locale. This is defined for locales which
|
||||
use extra decimal point and thousands-sep. */
|
||||
wctrans_t map = wctrans ("to_outpunct");
|
||||
wint_t wdecimal = towctrans (L_('.'), map);
|
||||
wint_t wthousands = towctrans (L_(','), map);
|
||||
|
||||
if (__builtin_expect (map != NULL, 0))
|
||||
{
|
||||
mbstate_t state;
|
||||
memset (&state, '\0', sizeof (state));
|
||||
|
||||
size_t n = wcrtomb (decimal, wdecimal, &state);
|
||||
if (n == (size_t) -1)
|
||||
memcpy (decimal, ".", 2);
|
||||
else
|
||||
decimal[n] = '\0';
|
||||
|
||||
memset (&state, '\0', sizeof (state));
|
||||
|
||||
n = wcrtomb (thousands, wthousands, &state);
|
||||
if (n == (size_t) -1)
|
||||
memcpy (thousands, ",", 2);
|
||||
else
|
||||
thousands[n] = '\0';
|
||||
}
|
||||
|
||||
/* Copy existing string so that nothing gets overwritten. */
|
||||
char *src;
|
||||
int use_alloca = (rear_ptr - w) < 4096;
|
||||
if (__builtin_expect (use_alloca, 1))
|
||||
src = (char *) alloca (rear_ptr - w);
|
||||
else
|
||||
{
|
||||
src = (char *) malloc (rear_ptr - w);
|
||||
if (src == NULL)
|
||||
/* If we cannot allocate the memory don't rewrite the string.
|
||||
It is better than nothing. */
|
||||
return w;
|
||||
}
|
||||
|
||||
memcpy (src, w, rear_ptr - w);
|
||||
char *s = src + (rear_ptr - w);
|
||||
|
||||
w = end;
|
||||
|
||||
/* Process all characters in the string. */
|
||||
while (--s >= src)
|
||||
{
|
||||
if (*s >= '0' && *s <= '9')
|
||||
{
|
||||
if (sizeof (char) == 1)
|
||||
w = (char *) outdigit_value ((char *) w, *s - '0');
|
||||
else
|
||||
*--w = (char) outdigitwc_value (*s - '0');
|
||||
}
|
||||
else if (__builtin_expect (map == NULL, 1) || (*s != '.' && *s != ','))
|
||||
*--w = *s;
|
||||
else
|
||||
{
|
||||
if (sizeof (char) == 1)
|
||||
{
|
||||
const char *outpunct = *s == '.' ? decimal : thousands;
|
||||
size_t dlen = strlen (outpunct);
|
||||
|
||||
w -= dlen;
|
||||
while (dlen-- > 0)
|
||||
w[dlen] = outpunct[dlen];
|
||||
}
|
||||
else
|
||||
*--w = *s == '.' ? (char) wdecimal : (char) wthousands;
|
||||
}
|
||||
}
|
||||
|
||||
if (! use_alloca)
|
||||
free (src);
|
||||
|
||||
return w;
|
||||
}
|
77
libquadmath/printf/_itoa.h
Normal file
77
libquadmath/printf/_itoa.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* Internal function for converting integers to ASCII.
|
||||
Copyright (C) 1994-1999,2002,2003,2007 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _ITOA_H
|
||||
#define _ITOA_H
|
||||
|
||||
/* Convert VALUE into ASCII in base BASE (2..16).
|
||||
Write backwards starting the character just before BUFLIM.
|
||||
Return the address of the first (left-to-right) character in the number.
|
||||
Use upper case letters iff UPPER_CASE is nonzero. */
|
||||
|
||||
static const char _itoa_lower_digits[16] = "0123456789abcdef";
|
||||
static const char _itoa_upper_digits[16] = "0123456789ABCDEF";
|
||||
|
||||
static inline char * __attribute__ ((unused, always_inline))
|
||||
_itoa_word (unsigned long value, char *buflim,
|
||||
unsigned int base, int upper_case)
|
||||
{
|
||||
const char *digits = (upper_case ? _itoa_upper_digits : _itoa_lower_digits);
|
||||
|
||||
switch (base)
|
||||
{
|
||||
# define SPECIAL(Base) \
|
||||
case Base: \
|
||||
do \
|
||||
*--buflim = digits[value % Base]; \
|
||||
while ((value /= Base) != 0); \
|
||||
break
|
||||
|
||||
SPECIAL (10);
|
||||
SPECIAL (16);
|
||||
SPECIAL (8);
|
||||
default:
|
||||
do
|
||||
*--buflim = digits[value % base];
|
||||
while ((value /= base) != 0);
|
||||
}
|
||||
return buflim;
|
||||
}
|
||||
|
||||
static inline char * __attribute__ ((unused, always_inline))
|
||||
_itoa (uint64_t value, char *buflim,
|
||||
unsigned int base, int upper_case)
|
||||
{
|
||||
const char *digits = (upper_case ? _itoa_upper_digits : _itoa_lower_digits);
|
||||
|
||||
switch (base)
|
||||
{
|
||||
SPECIAL (10);
|
||||
SPECIAL (16);
|
||||
SPECIAL (8);
|
||||
default:
|
||||
do
|
||||
*--buflim = digits[value % base];
|
||||
while ((value /= base) != 0);
|
||||
}
|
||||
return buflim;
|
||||
}
|
||||
# undef SPECIAL
|
||||
|
||||
#endif /* itoa.h */
|
83
libquadmath/printf/_itowa.h
Normal file
83
libquadmath/printf/_itowa.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* Internal function for converting integers to ASCII.
|
||||
Copyright (C) 1994,95,96,97,98,99,2002,2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _ITOWA_H
|
||||
#define _ITOWA_H 1
|
||||
|
||||
/* Convert VALUE into ASCII in base BASE (2..16).
|
||||
Write backwards starting the character just before BUFLIM.
|
||||
Return the address of the first (left-to-right) character in the number.
|
||||
Use upper case letters iff UPPER_CASE is nonzero. */
|
||||
|
||||
static const wchar_t _itowa_lower_digits[16] = L_("0123456789abcdef");
|
||||
static const wchar_t _itowa_upper_digits[16] = L_("0123456789ABCDEF");
|
||||
|
||||
static inline wchar_t *
|
||||
__attribute__ ((unused, always_inline))
|
||||
_itowa_word (unsigned long value, wchar_t *buflim,
|
||||
unsigned int base, int upper_case)
|
||||
{
|
||||
const wchar_t *digits = (upper_case
|
||||
? _itowa_upper_digits : _itowa_lower_digits);
|
||||
wchar_t *bp = buflim;
|
||||
|
||||
switch (base)
|
||||
{
|
||||
#define SPECIAL(Base) \
|
||||
case Base: \
|
||||
do \
|
||||
*--bp = digits[value % Base]; \
|
||||
while ((value /= Base) != 0); \
|
||||
break
|
||||
|
||||
SPECIAL (10);
|
||||
SPECIAL (16);
|
||||
SPECIAL (8);
|
||||
default:
|
||||
do
|
||||
*--bp = digits[value % base];
|
||||
while ((value /= base) != 0);
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
|
||||
static inline wchar_t *
|
||||
__attribute__ ((unused, always_inline))
|
||||
_itowa (uint64_t value, wchar_t *buflim,
|
||||
unsigned int base, int upper_case)
|
||||
{
|
||||
const wchar_t *digits = (upper_case
|
||||
? _itowa_upper_digits : _itowa_lower_digits);
|
||||
wchar_t *bp = buflim;
|
||||
|
||||
switch (base)
|
||||
{
|
||||
SPECIAL (10);
|
||||
SPECIAL (16);
|
||||
SPECIAL (8);
|
||||
default:
|
||||
do
|
||||
*--bp = digits[value % base];
|
||||
while ((value /= base) != 0);
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
#undef SPECIAL
|
||||
|
||||
#endif /* itowa.h */
|
61
libquadmath/printf/add_n.c
Normal file
61
libquadmath/printf/add_n.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* mpn_add_n -- Add two limb vectors of equal, non-zero length.
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
|
||||
#else
|
||||
mpn_add_n (res_ptr, s1_ptr, s2_ptr, size)
|
||||
register mp_ptr res_ptr;
|
||||
register mp_srcptr s1_ptr;
|
||||
register mp_srcptr s2_ptr;
|
||||
mp_size_t size;
|
||||
#endif
|
||||
{
|
||||
register mp_limb_t x, y, cy;
|
||||
register mp_size_t j;
|
||||
|
||||
/* The loop counter and index J goes from -SIZE to -1. This way
|
||||
the loop becomes faster. */
|
||||
j = -size;
|
||||
|
||||
/* Offset the base pointers to compensate for the negative indices. */
|
||||
s1_ptr -= j;
|
||||
s2_ptr -= j;
|
||||
res_ptr -= j;
|
||||
|
||||
cy = 0;
|
||||
do
|
||||
{
|
||||
y = s2_ptr[j];
|
||||
x = s1_ptr[j];
|
||||
y += cy; /* add previous carry to one addend */
|
||||
cy = (y < cy); /* get out carry from that addition */
|
||||
y = x + y; /* add other addend */
|
||||
cy = (y < x) + cy; /* get out carry from that add, combine */
|
||||
res_ptr[j] = y;
|
||||
}
|
||||
while (++j != 0);
|
||||
|
||||
return cy;
|
||||
}
|
63
libquadmath/printf/addmul_1.c
Normal file
63
libquadmath/printf/addmul_1.c
Normal file
@ -0,0 +1,63 @@
|
||||
/* mpn_addmul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR
|
||||
by S2_LIMB, add the S1_SIZE least significant limbs of the product to the
|
||||
limb vector pointed to by RES_PTR. Return the most significant limb of
|
||||
the product, adjusted for carry-out from the addition.
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
mp_limb_t
|
||||
mpn_addmul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
|
||||
register mp_ptr res_ptr;
|
||||
register mp_srcptr s1_ptr;
|
||||
mp_size_t s1_size;
|
||||
register mp_limb_t s2_limb;
|
||||
{
|
||||
register mp_limb_t cy_limb;
|
||||
register mp_size_t j;
|
||||
register mp_limb_t prod_high, prod_low;
|
||||
register mp_limb_t x;
|
||||
|
||||
/* The loop counter and index J goes from -SIZE to -1. This way
|
||||
the loop becomes faster. */
|
||||
j = -s1_size;
|
||||
|
||||
/* Offset the base pointers to compensate for the negative indices. */
|
||||
res_ptr -= j;
|
||||
s1_ptr -= j;
|
||||
|
||||
cy_limb = 0;
|
||||
do
|
||||
{
|
||||
umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
|
||||
|
||||
prod_low += cy_limb;
|
||||
cy_limb = (prod_low < cy_limb) + prod_high;
|
||||
|
||||
x = res_ptr[j];
|
||||
prod_low = x + prod_low;
|
||||
cy_limb += (prod_low < x);
|
||||
res_ptr[j] = prod_low;
|
||||
}
|
||||
while (++j != 0);
|
||||
|
||||
return cy_limb;
|
||||
}
|
55
libquadmath/printf/cmp.c
Normal file
55
libquadmath/printf/cmp.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* mpn_cmp -- Compare two low-level natural-number integers.
|
||||
|
||||
Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
|
||||
There are no restrictions on the relative sizes of
|
||||
the two arguments.
|
||||
Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2. */
|
||||
|
||||
int
|
||||
#if __STDC__
|
||||
mpn_cmp (mp_srcptr op1_ptr, mp_srcptr op2_ptr, mp_size_t size)
|
||||
#else
|
||||
mpn_cmp (op1_ptr, op2_ptr, size)
|
||||
mp_srcptr op1_ptr;
|
||||
mp_srcptr op2_ptr;
|
||||
mp_size_t size;
|
||||
#endif
|
||||
{
|
||||
mp_size_t i;
|
||||
mp_limb_t op1_word, op2_word;
|
||||
|
||||
for (i = size - 1; i >= 0; i--)
|
||||
{
|
||||
op1_word = op1_ptr[i];
|
||||
op2_word = op2_ptr[i];
|
||||
if (op1_word != op2_word)
|
||||
goto diff;
|
||||
}
|
||||
return 0;
|
||||
diff:
|
||||
/* This can *not* be simplified to
|
||||
op2_word - op2_word
|
||||
since that expression might give signed overflow. */
|
||||
return (op1_word > op2_word) ? 1 : -1;
|
||||
}
|
243
libquadmath/printf/divrem.c
Normal file
243
libquadmath/printf/divrem.c
Normal file
@ -0,0 +1,243 @@
|
||||
/* mpn_divrem -- Divide natural numbers, producing both remainder and
|
||||
quotient.
|
||||
|
||||
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
|
||||
the NSIZE-DSIZE least significant quotient limbs at QP
|
||||
and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
|
||||
non-zero, generate that many fraction bits and append them after the
|
||||
other quotient limbs.
|
||||
Return the most significant limb of the quotient, this is always 0 or 1.
|
||||
|
||||
Preconditions:
|
||||
0. NSIZE >= DSIZE.
|
||||
1. The most significant bit of the divisor must be set.
|
||||
2. QP must either not overlap with the input operands at all, or
|
||||
QP + DSIZE >= NP must hold true. (This means that it's
|
||||
possible to put the quotient in the high part of NUM, right after the
|
||||
remainder in NUM.
|
||||
3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero. */
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_divrem (mp_ptr qp, mp_size_t qextra_limbs,
|
||||
mp_ptr np, mp_size_t nsize,
|
||||
mp_srcptr dp, mp_size_t dsize)
|
||||
#else
|
||||
mpn_divrem (qp, qextra_limbs, np, nsize, dp, dsize)
|
||||
mp_ptr qp;
|
||||
mp_size_t qextra_limbs;
|
||||
mp_ptr np;
|
||||
mp_size_t nsize;
|
||||
mp_srcptr dp;
|
||||
mp_size_t dsize;
|
||||
#endif
|
||||
{
|
||||
mp_limb_t most_significant_q_limb = 0;
|
||||
|
||||
switch (dsize)
|
||||
{
|
||||
case 0:
|
||||
/* We are asked to divide by zero, so go ahead and do it! (To make
|
||||
the compiler not remove this statement, return the value.) */
|
||||
return 1 / dsize;
|
||||
|
||||
case 1:
|
||||
{
|
||||
mp_size_t i;
|
||||
mp_limb_t n1;
|
||||
mp_limb_t d;
|
||||
|
||||
d = dp[0];
|
||||
n1 = np[nsize - 1];
|
||||
|
||||
if (n1 >= d)
|
||||
{
|
||||
n1 -= d;
|
||||
most_significant_q_limb = 1;
|
||||
}
|
||||
|
||||
qp += qextra_limbs;
|
||||
for (i = nsize - 2; i >= 0; i--)
|
||||
udiv_qrnnd (qp[i], n1, n1, np[i], d);
|
||||
qp -= qextra_limbs;
|
||||
|
||||
for (i = qextra_limbs - 1; i >= 0; i--)
|
||||
udiv_qrnnd (qp[i], n1, n1, 0, d);
|
||||
|
||||
np[0] = n1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
mp_size_t i;
|
||||
mp_limb_t n1, n0, n2;
|
||||
mp_limb_t d1, d0;
|
||||
|
||||
np += nsize - 2;
|
||||
d1 = dp[1];
|
||||
d0 = dp[0];
|
||||
n1 = np[1];
|
||||
n0 = np[0];
|
||||
|
||||
if (n1 >= d1 && (n1 > d1 || n0 >= d0))
|
||||
{
|
||||
sub_ddmmss (n1, n0, n1, n0, d1, d0);
|
||||
most_significant_q_limb = 1;
|
||||
}
|
||||
|
||||
for (i = qextra_limbs + nsize - 2 - 1; i >= 0; i--)
|
||||
{
|
||||
mp_limb_t q;
|
||||
mp_limb_t r;
|
||||
|
||||
if (i >= qextra_limbs)
|
||||
np--;
|
||||
else
|
||||
np[0] = 0;
|
||||
|
||||
if (n1 == d1)
|
||||
{
|
||||
/* Q should be either 111..111 or 111..110. Need special
|
||||
treatment of this rare case as normal division would
|
||||
give overflow. */
|
||||
q = ~(mp_limb_t) 0;
|
||||
|
||||
r = n0 + d1;
|
||||
if (r < d1) /* Carry in the addition? */
|
||||
{
|
||||
add_ssaaaa (n1, n0, r - d0, np[0], 0, d0);
|
||||
qp[i] = q;
|
||||
continue;
|
||||
}
|
||||
n1 = d0 - (d0 != 0);
|
||||
n0 = -d0;
|
||||
}
|
||||
else
|
||||
{
|
||||
udiv_qrnnd (q, r, n1, n0, d1);
|
||||
umul_ppmm (n1, n0, d0, q);
|
||||
}
|
||||
|
||||
n2 = np[0];
|
||||
q_test:
|
||||
if (n1 > r || (n1 == r && n0 > n2))
|
||||
{
|
||||
/* The estimated Q was too large. */
|
||||
q--;
|
||||
|
||||
sub_ddmmss (n1, n0, n1, n0, 0, d0);
|
||||
r += d1;
|
||||
if (r >= d1) /* If not carry, test Q again. */
|
||||
goto q_test;
|
||||
}
|
||||
|
||||
qp[i] = q;
|
||||
sub_ddmmss (n1, n0, r, n2, n1, n0);
|
||||
}
|
||||
np[1] = n1;
|
||||
np[0] = n0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
mp_size_t i;
|
||||
mp_limb_t dX, d1, n0;
|
||||
|
||||
np += nsize - dsize;
|
||||
dX = dp[dsize - 1];
|
||||
d1 = dp[dsize - 2];
|
||||
n0 = np[dsize - 1];
|
||||
|
||||
if (n0 >= dX)
|
||||
{
|
||||
if (n0 > dX || mpn_cmp (np, dp, dsize - 1) >= 0)
|
||||
{
|
||||
mpn_sub_n (np, np, dp, dsize);
|
||||
n0 = np[dsize - 1];
|
||||
most_significant_q_limb = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = qextra_limbs + nsize - dsize - 1; i >= 0; i--)
|
||||
{
|
||||
mp_limb_t q;
|
||||
mp_limb_t n1, n2;
|
||||
mp_limb_t cy_limb;
|
||||
|
||||
if (i >= qextra_limbs)
|
||||
{
|
||||
np--;
|
||||
n2 = np[dsize];
|
||||
}
|
||||
else
|
||||
{
|
||||
n2 = np[dsize - 1];
|
||||
MPN_COPY_DECR (np + 1, np, dsize);
|
||||
np[0] = 0;
|
||||
}
|
||||
|
||||
if (n0 == dX)
|
||||
/* This might over-estimate q, but it's probably not worth
|
||||
the extra code here to find out. */
|
||||
q = ~(mp_limb_t) 0;
|
||||
else
|
||||
{
|
||||
mp_limb_t r;
|
||||
|
||||
udiv_qrnnd (q, r, n0, np[dsize - 1], dX);
|
||||
umul_ppmm (n1, n0, d1, q);
|
||||
|
||||
while (n1 > r || (n1 == r && n0 > np[dsize - 2]))
|
||||
{
|
||||
q--;
|
||||
r += dX;
|
||||
if (r < dX) /* I.e. "carry in previous addition?" */
|
||||
break;
|
||||
n1 -= n0 < d1;
|
||||
n0 -= d1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Possible optimization: We already have (q * n0) and (1 * n1)
|
||||
after the calculation of q. Taking advantage of that, we
|
||||
could make this loop make two iterations less. */
|
||||
|
||||
cy_limb = mpn_submul_1 (np, dp, dsize, q);
|
||||
|
||||
if (n2 != cy_limb)
|
||||
{
|
||||
mpn_add_n (np, np, dp, dsize);
|
||||
q--;
|
||||
}
|
||||
|
||||
qp[i] = q;
|
||||
n0 = np[dsize - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return most_significant_q_limb;
|
||||
}
|
136
libquadmath/printf/flt1282mpn.c
Normal file
136
libquadmath/printf/flt1282mpn.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* Copyright (C) 1995,1996,1997,1998,1999,2002,2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Convert a `__float128' in IEEE854 quad-precision format to a
|
||||
multi-precision integer representing the significand scaled up by its
|
||||
number of bits (113 for long double) and an integral power of two
|
||||
(MPN frexpl). */
|
||||
|
||||
mp_size_t
|
||||
mpn_extract_flt128 (mp_ptr res_ptr, mp_size_t size,
|
||||
int *expt, int *is_neg,
|
||||
__float128 value)
|
||||
{
|
||||
ieee854_float128 u;
|
||||
u.value = value;
|
||||
|
||||
*is_neg = u.ieee.negative;
|
||||
*expt = (int) u.ieee.exponent - IEEE854_FLOAT128_BIAS;
|
||||
|
||||
#if BITS_PER_MP_LIMB == 32
|
||||
res_ptr[0] = u.ieee.mant_low; /* Low-order 32 bits of fraction. */
|
||||
res_ptr[1] = (u.ieee.mant_low >> 32);
|
||||
res_ptr[2] = u.ieee.mant_high;
|
||||
res_ptr[3] = (u.ieee.mant_high >> 32); /* High-order 32 bits. */
|
||||
#define N 4
|
||||
#elif BITS_PER_MP_LIMB == 64
|
||||
res_ptr[0] = u.ieee.mant_low;
|
||||
res_ptr[1] = u.ieee.mant_high;
|
||||
#define N 2
|
||||
#else
|
||||
#error "mp_limb size " BITS_PER_MP_LIMB "not accounted for"
|
||||
#endif
|
||||
/* The format does not fill the last limb. There are some zeros. */
|
||||
#define NUM_LEADING_ZEROS (BITS_PER_MP_LIMB \
|
||||
- (FLT128_MANT_DIG - ((N - 1) * BITS_PER_MP_LIMB)))
|
||||
|
||||
if (u.ieee.exponent == 0)
|
||||
{
|
||||
/* A biased exponent of zero is a special case.
|
||||
Either it is a zero or it is a denormal number. */
|
||||
if (res_ptr[0] == 0 && res_ptr[1] == 0
|
||||
&& res_ptr[N - 2] == 0 && res_ptr[N - 1] == 0) /* Assumes N<=4. */
|
||||
/* It's zero. */
|
||||
*expt = 0;
|
||||
else
|
||||
{
|
||||
/* It is a denormal number, meaning it has no implicit leading
|
||||
one bit, and its exponent is in fact the format minimum. */
|
||||
int cnt;
|
||||
|
||||
#if N == 2
|
||||
if (res_ptr[N - 1] != 0)
|
||||
{
|
||||
count_leading_zeros (cnt, res_ptr[N - 1]);
|
||||
cnt -= NUM_LEADING_ZEROS;
|
||||
res_ptr[N - 1] = res_ptr[N - 1] << cnt
|
||||
| (res_ptr[0] >> (BITS_PER_MP_LIMB - cnt));
|
||||
res_ptr[0] <<= cnt;
|
||||
*expt = FLT128_MIN_EXP - 1 - cnt;
|
||||
}
|
||||
else
|
||||
{
|
||||
count_leading_zeros (cnt, res_ptr[0]);
|
||||
if (cnt >= NUM_LEADING_ZEROS)
|
||||
{
|
||||
res_ptr[N - 1] = res_ptr[0] << (cnt - NUM_LEADING_ZEROS);
|
||||
res_ptr[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
res_ptr[N - 1] = res_ptr[0] >> (NUM_LEADING_ZEROS - cnt);
|
||||
res_ptr[0] <<= BITS_PER_MP_LIMB - (NUM_LEADING_ZEROS - cnt);
|
||||
}
|
||||
*expt = FLT128_MIN_EXP - 1
|
||||
- (BITS_PER_MP_LIMB - NUM_LEADING_ZEROS) - cnt;
|
||||
}
|
||||
#else
|
||||
int j, k, l;
|
||||
|
||||
for (j = N - 1; j > 0; j--)
|
||||
if (res_ptr[j] != 0)
|
||||
break;
|
||||
|
||||
count_leading_zeros (cnt, res_ptr[j]);
|
||||
cnt -= NUM_LEADING_ZEROS;
|
||||
l = N - 1 - j;
|
||||
if (cnt < 0)
|
||||
{
|
||||
cnt += BITS_PER_MP_LIMB;
|
||||
l--;
|
||||
}
|
||||
if (!cnt)
|
||||
for (k = N - 1; k >= l; k--)
|
||||
res_ptr[k] = res_ptr[k-l];
|
||||
else
|
||||
{
|
||||
for (k = N - 1; k > l; k--)
|
||||
res_ptr[k] = res_ptr[k-l] << cnt
|
||||
| res_ptr[k-l-1] >> (BITS_PER_MP_LIMB - cnt);
|
||||
res_ptr[k--] = res_ptr[0] << cnt;
|
||||
}
|
||||
|
||||
for (; k >= 0; k--)
|
||||
res_ptr[k] = 0;
|
||||
*expt = FLT128_MIN_EXP - 1 - l * BITS_PER_MP_LIMB - cnt;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Add the implicit leading one bit for a normalized number. */
|
||||
res_ptr[N - 1] |= (mp_limb_t) 1 << (FLT128_MANT_DIG - 1
|
||||
- ((N - 1) * BITS_PER_MP_LIMB));
|
||||
|
||||
return N;
|
||||
}
|
462
libquadmath/printf/fpioconst.c
Normal file
462
libquadmath/printf/fpioconst.c
Normal file
@ -0,0 +1,462 @@
|
||||
/* Table of MP integer constants 10^(2^i), used for floating point <-> decimal.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include "gmp-impl.h" /* This defines BITS_PER_MP_LIMB. */
|
||||
#include "fpioconst.h"
|
||||
|
||||
/* First page : 32-bit limbs
|
||||
Second page : 64-bit limbs
|
||||
Last page : table of pointers
|
||||
*/
|
||||
|
||||
#if BITS_PER_MP_LIMB == 32
|
||||
|
||||
/* Table with constants of 10^(2^i), i=0..12 for 32-bit limbs. */
|
||||
|
||||
const mp_limb_t __tens[] =
|
||||
{
|
||||
#define TENS_P0_IDX 0
|
||||
#define TENS_P0_SIZE 3
|
||||
[TENS_P0_IDX] = 0x00000000, 0x00000000, 0x0000000a,
|
||||
|
||||
#define TENS_P1_IDX (TENS_P0_IDX + TENS_P0_SIZE)
|
||||
#define TENS_P1_SIZE 3
|
||||
[TENS_P1_IDX] = 0x00000000, 0x00000000, 0x00000064,
|
||||
|
||||
#define TENS_P2_IDX (TENS_P1_IDX + TENS_P1_SIZE)
|
||||
#define TENS_P2_SIZE 3
|
||||
[TENS_P2_IDX] = 0x00000000, 0x00000000, 0x00002710,
|
||||
|
||||
#define TENS_P3_IDX (TENS_P2_IDX + TENS_P2_SIZE)
|
||||
#define TENS_P3_SIZE 3
|
||||
[TENS_P3_IDX] = 0x00000000, 0x00000000, 0x05f5e100,
|
||||
|
||||
#define TENS_P4_IDX (TENS_P3_IDX + TENS_P3_SIZE)
|
||||
#define TENS_P4_SIZE 4
|
||||
[TENS_P4_IDX] = 0x00000000, 0x00000000, 0x6fc10000, 0x002386f2,
|
||||
|
||||
#define TENS_P5_IDX (TENS_P4_IDX + TENS_P4_SIZE)
|
||||
#define TENS_P5_SIZE 6
|
||||
[TENS_P5_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x85acef81, 0x2d6d415b,
|
||||
0x000004ee,
|
||||
|
||||
#define TENS_P6_IDX (TENS_P5_IDX + TENS_P5_SIZE)
|
||||
#define TENS_P6_SIZE 9
|
||||
[TENS_P6_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xbf6a1f01,
|
||||
0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03,
|
||||
|
||||
#define TENS_P7_IDX (TENS_P6_IDX + TENS_P6_SIZE)
|
||||
#define TENS_P7_SIZE 16
|
||||
[TENS_P7_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd, 0x2374e42f, 0xd3cff5ec,
|
||||
0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
|
||||
|
||||
#define TENS_P8_IDX (TENS_P7_IDX + TENS_P7_SIZE)
|
||||
#define TENS_P8_SIZE 29
|
||||
[TENS_P8_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x982e7c01,
|
||||
0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, 0xd595d80f,
|
||||
0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0,
|
||||
0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
|
||||
|
||||
#ifndef __NO_LONG_DOUBLE_MATH
|
||||
# define TENS_P9_IDX (TENS_P8_IDX + TENS_P8_SIZE)
|
||||
# define TENS_P9_SIZE 56
|
||||
[TENS_P9_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0xfc6cf801, 0x77f27267, 0x8f9546dc, 0x5d96976f, 0xb83a8a97,
|
||||
0xc31e1ad9, 0x46c40513, 0x94e65747, 0xc88976c1, 0x4475b579, 0x28f8733b,
|
||||
0xaa1da1bf, 0x703ed321, 0x1e25cfea, 0xb21a2f22, 0xbc51fb2e, 0x96e14f5d,
|
||||
0xbfa3edac, 0x329c57ae, 0xe7fc7153, 0xc3fc0695, 0x85a91924, 0xf95f635e,
|
||||
0xb2908ee0, 0x93abade4, 0x1366732a, 0x9449775c, 0x69be5b0e, 0x7343afac,
|
||||
0xb099bc81, 0x45a71d46, 0xa2699748, 0x8cb07303, 0x8a0b1f13, 0x8cab8a97,
|
||||
0xc1d238d9, 0x633415d4, 0x0000001c,
|
||||
|
||||
# define TENS_P10_IDX (TENS_P9_IDX + TENS_P9_SIZE)
|
||||
# define TENS_P10_SIZE 109
|
||||
[TENS_P10_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2919f001,
|
||||
0xf55b2b72, 0x6e7c215b, 0x1ec29f86, 0x991c4e87, 0x15c51a88, 0x140ac535,
|
||||
0x4c7d1e1a, 0xcc2cd819, 0x0ed1440e, 0x896634ee, 0x7de16cfb, 0x1e43f61f,
|
||||
0x9fce837d, 0x231d2b9c, 0x233e55c7, 0x65dc60d7, 0xf451218b, 0x1c5cd134,
|
||||
0xc9635986, 0x922bbb9f, 0xa7e89431, 0x9f9f2a07, 0x62be695a, 0x8e1042c4,
|
||||
0x045b7a74, 0x1abe1de3, 0x8ad822a5, 0xba34c411, 0xd814b505, 0xbf3fdeb3,
|
||||
0x8fc51a16, 0xb1b896bc, 0xf56deeec, 0x31fb6bfd, 0xb6f4654b, 0x101a3616,
|
||||
0x6b7595fb, 0xdc1a47fe, 0x80d98089, 0x80bda5a5, 0x9a202882, 0x31eb0f66,
|
||||
0xfc8f1f90, 0x976a3310, 0xe26a7b7e, 0xdf68368a, 0x3ce3a0b8, 0x8e4262ce,
|
||||
0x75a351a2, 0x6cb0b6c9, 0x44597583, 0x31b5653f, 0xc356e38a, 0x35faaba6,
|
||||
0x0190fba0, 0x9fc4ed52, 0x88bc491b, 0x1640114a, 0x005b8041, 0xf4f3235e,
|
||||
0x1e8d4649, 0x36a8de06, 0x73c55349, 0xa7e6bd2a, 0xc1a6970c, 0x47187094,
|
||||
0xd2db49ef, 0x926c3f5b, 0xae6209d4, 0x2d433949, 0x34f4a3c6, 0xd4305d94,
|
||||
0xd9d61a05, 0x00000325,
|
||||
|
||||
# define TENS_P11_IDX (TENS_P10_IDX + TENS_P10_SIZE)
|
||||
# define TENS_P11_SIZE 215
|
||||
[TENS_P11_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x1333e001, 0xe3096865, 0xb27d4d3f, 0x49e28dcf, 0xec2e4721,
|
||||
0xee87e354, 0xb6067584, 0x368b8abb, 0xa5e5a191, 0x2ed56d55, 0xfd827773,
|
||||
0xea50d142, 0x51b78db2, 0x98342c9e, 0xc850dabc, 0x866ed6f1, 0x19342c12,
|
||||
0x92794987, 0xd2f869c2, 0x66912e4a, 0x71c7fd8f, 0x57a7842d, 0x235552eb,
|
||||
0xfb7fedcc, 0xf3861ce0, 0x38209ce1, 0x9713b449, 0x34c10134, 0x8c6c54de,
|
||||
0xa7a8289c, 0x2dbb6643, 0xe3cb64f3, 0x8074ff01, 0xe3892ee9, 0x10c17f94,
|
||||
0xa8f16f92, 0xa8281ed6, 0x967abbb3, 0x5a151440, 0x9952fbed, 0x13b41e44,
|
||||
0xafe609c3, 0xa2bca416, 0xf111821f, 0xfb1264b4, 0x91bac974, 0xd6c7d6ab,
|
||||
0x8e48ff35, 0x4419bd43, 0xc4a65665, 0x685e5510, 0x33554c36, 0xab498697,
|
||||
0x0dbd21fe, 0x3cfe491d, 0x982da466, 0xcbea4ca7, 0x9e110c7b, 0x79c56b8a,
|
||||
0x5fc5a047, 0x84d80e2e, 0x1aa9f444, 0x730f203c, 0x6a57b1ab, 0xd752f7a6,
|
||||
0x87a7dc62, 0x944545ff, 0x40660460, 0x77c1a42f, 0xc9ac375d, 0xe866d7ef,
|
||||
0x744695f0, 0x81428c85, 0xa1fc6b96, 0xd7917c7b, 0x7bf03c19, 0x5b33eb41,
|
||||
0x5715f791, 0x8f6cae5f, 0xdb0708fd, 0xb125ac8e, 0x785ce6b7, 0x56c6815b,
|
||||
0x6f46eadb, 0x4eeebeee, 0x195355d8, 0xa244de3c, 0x9d7389c0, 0x53761abd,
|
||||
0xcf99d019, 0xde9ec24b, 0x0d76ce39, 0x70beb181, 0x2e55ecee, 0xd5f86079,
|
||||
0xf56d9d4b, 0xfb8886fb, 0x13ef5a83, 0x408f43c5, 0x3f3389a4, 0xfad37943,
|
||||
0x58ccf45c, 0xf82df846, 0x415c7f3e, 0x2915e818, 0x8b3d5cf4, 0x6a445f27,
|
||||
0xf8dbb57a, 0xca8f0070, 0x8ad803ec, 0xb2e87c34, 0x038f9245, 0xbedd8a6c,
|
||||
0xc7c9dee0, 0x0eac7d56, 0x2ad3fa14, 0xe0de0840, 0xf775677c, 0xf1bd0ad5,
|
||||
0x92be221e, 0x87fa1fb9, 0xce9d04a4, 0xd2c36fa9, 0x3f6f7024, 0xb028af62,
|
||||
0x907855ee, 0xd83e49d6, 0x4efac5dc, 0xe7151aab, 0x77cd8c6b, 0x0a753b7d,
|
||||
0x0af908b4, 0x8c983623, 0xe50f3027, 0x94222771, 0x1d08e2d6, 0xf7e928e6,
|
||||
0xf2ee5ca6, 0x1b61b93c, 0x11eb962b, 0x9648b21c, 0xce2bcba1, 0x34f77154,
|
||||
0x7bbebe30, 0xe526a319, 0x8ce329ac, 0xde4a74d2, 0xb5dc53d5, 0x0009e8b3,
|
||||
|
||||
# define TENS_P12_IDX (TENS_P11_IDX + TENS_P11_SIZE)
|
||||
# define TENS_P12_SIZE 428
|
||||
[TENS_P12_IDX] = 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2a67c001,
|
||||
0xd4724e8d, 0x8efe7ae7, 0xf89a1e90, 0xef084117, 0x54e05154, 0x13b1bb51,
|
||||
0x506be829, 0xfb29b172, 0xe599574e, 0xf0da6146, 0x806c0ed3, 0xb86ae5be,
|
||||
0x45155e93, 0xc0591cc2, 0x7e1e7c34, 0x7c4823da, 0x1d1f4cce, 0x9b8ba1e8,
|
||||
0xd6bfdf75, 0xe341be10, 0xc2dfae78, 0x016b67b2, 0x0f237f1a, 0x3dbeabcd,
|
||||
0xaf6a2574, 0xcab3e6d7, 0x142e0e80, 0x61959127, 0x2c234811, 0x87009701,
|
||||
0xcb4bf982, 0xf8169c84, 0x88052f8c, 0x68dde6d4, 0xbc131761, 0xff0b0905,
|
||||
0x54ab9c41, 0x7613b224, 0x1a1c304e, 0x3bfe167b, 0x441c2d47, 0x4f6cea9c,
|
||||
0x78f06181, 0xeb659fb8, 0x30c7ae41, 0x947e0d0e, 0xa1ebcad7, 0xd97d9556,
|
||||
0x2130504d, 0x1a8309cb, 0xf2acd507, 0x3f8ec72a, 0xfd82373a, 0x95a842bc,
|
||||
0x280f4d32, 0xf3618ac0, 0x811a4f04, 0x6dc3a5b4, 0xd3967a1b, 0x15b8c898,
|
||||
0xdcfe388f, 0x454eb2a0, 0x8738b909, 0x10c4e996, 0x2bd9cc11, 0x3297cd0c,
|
||||
0x655fec30, 0xae0725b1, 0xf4090ee8, 0x037d19ee, 0x398c6fed, 0x3b9af26b,
|
||||
0xc994a450, 0xb5341743, 0x75a697b2, 0xac50b9c1, 0x3ccb5b92, 0xffe06205,
|
||||
0xa8329761, 0xdfea5242, 0xeb83cadb, 0xe79dadf7, 0x3c20ee69, 0x1e0a6817,
|
||||
0x7021b97a, 0x743074fa, 0x176ca776, 0x77fb8af6, 0xeca19beb, 0x92baf1de,
|
||||
0xaf63b712, 0xde35c88b, 0xa4eb8f8c, 0xe137d5e9, 0x40b464a0, 0x87d1cde8,
|
||||
0x42923bbd, 0xcd8f62ff, 0x2e2690f3, 0x095edc16, 0x59c89f1b, 0x1fa8fd5d,
|
||||
0x5138753d, 0x390a2b29, 0x80152f18, 0x2dd8d925, 0xf984d83e, 0x7a872e74,
|
||||
0xc19e1faf, 0xed4d542d, 0xecf9b5d0, 0x9462ea75, 0xc53c0adf, 0x0caea134,
|
||||
0x37a2d439, 0xc8fa2e8a, 0x2181327e, 0x6e7bb827, 0x2d240820, 0x50be10e0,
|
||||
0x5893d4b8, 0xab312bb9, 0x1f2b2322, 0x440b3f25, 0xbf627ede, 0x72dac789,
|
||||
0xb608b895, 0x78787e2a, 0x86deb3f0, 0x6fee7aab, 0xbb9373f4, 0x27ecf57b,
|
||||
0xf7d8b57e, 0xfca26a9f, 0x3d04e8d2, 0xc9df13cb, 0x3172826a, 0xcd9e8d7c,
|
||||
0xa8fcd8e0, 0xb2c39497, 0x307641d9, 0x1cc939c1, 0x2608c4cf, 0xb6d1c7bf,
|
||||
0x3d326a7e, 0xeeaf19e6, 0x8e13e25f, 0xee63302b, 0x2dfe6d97, 0x25971d58,
|
||||
0xe41d3cc4, 0x0a80627c, 0xab8db59a, 0x9eea37c8, 0xe90afb77, 0x90ca19cf,
|
||||
0x9ee3352c, 0x3613c850, 0xfe78d682, 0x788f6e50, 0x5b060904, 0xb71bd1a4,
|
||||
0x3fecb534, 0xb32c450c, 0x20c33857, 0xa6e9cfda, 0x0239f4ce, 0x48497187,
|
||||
0xa19adb95, 0xb492ed8a, 0x95aca6a8, 0x4dcd6cd9, 0xcf1b2350, 0xfbe8b12a,
|
||||
0x1a67778c, 0x38eb3acc, 0xc32da383, 0xfb126ab1, 0xa03f40a8, 0xed5bf546,
|
||||
0xe9ce4724, 0x4c4a74fd, 0x73a130d8, 0xd9960e2d, 0xa2ebd6c1, 0x94ab6feb,
|
||||
0x6f233b7c, 0x49126080, 0x8e7b9a73, 0x4b8c9091, 0xd298f999, 0x35e836b5,
|
||||
0xa96ddeff, 0x96119b31, 0x6b0dd9bc, 0xc6cc3f8d, 0x282566fb, 0x72b882e7,
|
||||
0xd6769f3b, 0xa674343d, 0x00fc509b, 0xdcbf7789, 0xd6266a3f, 0xae9641fd,
|
||||
0x4e89541b, 0x11953407, 0x53400d03, 0x8e0dd75a, 0xe5b53345, 0x108f19ad,
|
||||
0x108b89bc, 0x41a4c954, 0xe03b2b63, 0x437b3d7f, 0x97aced8e, 0xcbd66670,
|
||||
0x2c5508c2, 0x650ebc69, 0x5c4f2ef0, 0x904ff6bf, 0x9985a2df, 0x9faddd9e,
|
||||
0x5ed8d239, 0x25585832, 0xe3e51cb9, 0x0ff4f1d4, 0x56c02d9a, 0x8c4ef804,
|
||||
0xc1a08a13, 0x13fd01c8, 0xe6d27671, 0xa7c234f4, 0x9d0176cc, 0xd0d73df2,
|
||||
0x4d8bfa89, 0x544f10cd, 0x2b17e0b2, 0xb70a5c7d, 0xfd86fe49, 0xdf373f41,
|
||||
0x214495bb, 0x84e857fd, 0x00d313d5, 0x0496fcbe, 0xa4ba4744, 0xe8cac982,
|
||||
0xaec29e6e, 0x87ec7038, 0x7000a519, 0xaeee333b, 0xff66e42c, 0x8afd6b25,
|
||||
0x03b4f63b, 0xbd7991dc, 0x5ab8d9c7, 0x2ed4684e, 0x48741a6c, 0xaf06940d,
|
||||
0x2fdc6349, 0xb03d7ecd, 0xe974996f, 0xac7867f9, 0x52ec8721, 0xbcdd9d4a,
|
||||
0x8edd2d00, 0x3557de06, 0x41c759f8, 0x3956d4b9, 0xa75409f2, 0x123cd8a1,
|
||||
0xb6100fab, 0x3e7b21e2, 0x2e8d623b, 0x92959da2, 0xbca35f77, 0x200c03a5,
|
||||
0x35fcb457, 0x1bb6c6e4, 0xf74eb928, 0x3d5d0b54, 0x87cc1d21, 0x4964046f,
|
||||
0x18ae4240, 0xd868b275, 0x8bd2b496, 0x1c5563f4, 0xc234d8f5, 0xf868e970,
|
||||
0xf9151fff, 0xae7be4a2, 0x271133ee, 0xbb0fd922, 0x25254932, 0xa60a9fc0,
|
||||
0x104bcd64, 0x30290145, 0x00000062
|
||||
#endif /* !__NO_LONG_DOUBLE_MATH */
|
||||
};
|
||||
|
||||
#elif BITS_PER_MP_LIMB == 64
|
||||
|
||||
/* Table with constants of 10^(2^i), i=0..12 for 64-bit limbs. */
|
||||
|
||||
const mp_limb_t __tens[] =
|
||||
{
|
||||
#define TENS_P0_IDX 0
|
||||
#define TENS_P0_SIZE 2
|
||||
[TENS_P0_IDX] = 0x0000000000000000ull, 0x000000000000000aull,
|
||||
|
||||
#define TENS_P1_IDX (TENS_P0_IDX + TENS_P0_SIZE)
|
||||
#define TENS_P1_SIZE 2
|
||||
[TENS_P1_IDX] = 0x0000000000000000ull, 0x0000000000000064ull,
|
||||
|
||||
#define TENS_P2_IDX (TENS_P1_IDX + TENS_P1_SIZE)
|
||||
#define TENS_P2_SIZE 2
|
||||
[TENS_P2_IDX] = 0x0000000000000000ull, 0x0000000000002710ull,
|
||||
|
||||
#define TENS_P3_IDX (TENS_P2_IDX + TENS_P2_SIZE)
|
||||
#define TENS_P3_SIZE 2
|
||||
[TENS_P3_IDX] = 0x0000000000000000ull, 0x0000000005f5e100ull,
|
||||
|
||||
#define TENS_P4_IDX (TENS_P3_IDX + TENS_P3_SIZE)
|
||||
#define TENS_P4_SIZE 2
|
||||
[TENS_P4_IDX] = 0x0000000000000000ull, 0x002386f26fc10000ull,
|
||||
|
||||
#define TENS_P5_IDX (TENS_P4_IDX + TENS_P4_SIZE)
|
||||
#define TENS_P5_SIZE 3
|
||||
[TENS_P5_IDX] = 0x0000000000000000ull, 0x85acef8100000000ull,
|
||||
0x000004ee2d6d415bull,
|
||||
|
||||
#define TENS_P6_IDX (TENS_P5_IDX + TENS_P5_SIZE)
|
||||
#define TENS_P6_SIZE 5
|
||||
[TENS_P6_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x6e38ed64bf6a1f01ull, 0xe93ff9f4daa797edull, 0x0000000000184f03ull,
|
||||
|
||||
#define TENS_P7_IDX (TENS_P6_IDX + TENS_P6_SIZE)
|
||||
#define TENS_P7_SIZE 8
|
||||
[TENS_P7_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x03df99092e953e01ull, 0x2374e42f0f1538fdull,
|
||||
0xc404dc08d3cff5ecull, 0xa6337f19bccdb0daull, 0x0000024ee91f2603ull,
|
||||
|
||||
#define TENS_P8_IDX (TENS_P7_IDX + TENS_P7_SIZE)
|
||||
#define TENS_P8_SIZE 15
|
||||
[TENS_P8_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xbed3875b982e7c01ull, 0x12152f87d8d99f72ull, 0xcf4a6e706bde50c6ull,
|
||||
0x26b2716ed595d80full, 0x1d153624adc666b0ull, 0x63ff540e3c42d35aull,
|
||||
0x65f9ef17cc5573c0ull, 0x80dcc7f755bc28f2ull, 0x5fdcefcef46eeddcull,
|
||||
0x00000000000553f7ull,
|
||||
#if FLT128_MAX_EXP > 1024
|
||||
# define TENS_P9_IDX (TENS_P8_IDX + TENS_P8_SIZE)
|
||||
# define TENS_P9_SIZE 28
|
||||
[TENS_P9_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x77f27267fc6cf801ull, 0x5d96976f8f9546dcull,
|
||||
0xc31e1ad9b83a8a97ull, 0x94e6574746c40513ull, 0x4475b579c88976c1ull,
|
||||
0xaa1da1bf28f8733bull, 0x1e25cfea703ed321ull, 0xbc51fb2eb21a2f22ull,
|
||||
0xbfa3edac96e14f5dull, 0xe7fc7153329c57aeull, 0x85a91924c3fc0695ull,
|
||||
0xb2908ee0f95f635eull, 0x1366732a93abade4ull, 0x69be5b0e9449775cull,
|
||||
0xb099bc817343afacull, 0xa269974845a71d46ull, 0x8a0b1f138cb07303ull,
|
||||
0xc1d238d98cab8a97ull, 0x0000001c633415d4ull,
|
||||
|
||||
# define TENS_P10_IDX (TENS_P9_IDX + TENS_P9_SIZE)
|
||||
# define TENS_P10_SIZE 55
|
||||
[TENS_P10_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xf55b2b722919f001ull, 0x1ec29f866e7c215bull, 0x15c51a88991c4e87ull,
|
||||
0x4c7d1e1a140ac535ull, 0x0ed1440ecc2cd819ull, 0x7de16cfb896634eeull,
|
||||
0x9fce837d1e43f61full, 0x233e55c7231d2b9cull, 0xf451218b65dc60d7ull,
|
||||
0xc96359861c5cd134ull, 0xa7e89431922bbb9full, 0x62be695a9f9f2a07ull,
|
||||
0x045b7a748e1042c4ull, 0x8ad822a51abe1de3ull, 0xd814b505ba34c411ull,
|
||||
0x8fc51a16bf3fdeb3ull, 0xf56deeecb1b896bcull, 0xb6f4654b31fb6bfdull,
|
||||
0x6b7595fb101a3616ull, 0x80d98089dc1a47feull, 0x9a20288280bda5a5ull,
|
||||
0xfc8f1f9031eb0f66ull, 0xe26a7b7e976a3310ull, 0x3ce3a0b8df68368aull,
|
||||
0x75a351a28e4262ceull, 0x445975836cb0b6c9ull, 0xc356e38a31b5653full,
|
||||
0x0190fba035faaba6ull, 0x88bc491b9fc4ed52ull, 0x005b80411640114aull,
|
||||
0x1e8d4649f4f3235eull, 0x73c5534936a8de06ull, 0xc1a6970ca7e6bd2aull,
|
||||
0xd2db49ef47187094ull, 0xae6209d4926c3f5bull, 0x34f4a3c62d433949ull,
|
||||
0xd9d61a05d4305d94ull, 0x0000000000000325ull,
|
||||
|
||||
# define TENS_P11_IDX (TENS_P10_IDX + TENS_P10_SIZE)
|
||||
# define TENS_P11_SIZE 108
|
||||
[TENS_P11_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0xe30968651333e001ull, 0x49e28dcfb27d4d3full,
|
||||
0xee87e354ec2e4721ull, 0x368b8abbb6067584ull, 0x2ed56d55a5e5a191ull,
|
||||
0xea50d142fd827773ull, 0x98342c9e51b78db2ull, 0x866ed6f1c850dabcull,
|
||||
0x9279498719342c12ull, 0x66912e4ad2f869c2ull, 0x57a7842d71c7fd8full,
|
||||
0xfb7fedcc235552ebull, 0x38209ce1f3861ce0ull, 0x34c101349713b449ull,
|
||||
0xa7a8289c8c6c54deull, 0xe3cb64f32dbb6643ull, 0xe3892ee98074ff01ull,
|
||||
0xa8f16f9210c17f94ull, 0x967abbb3a8281ed6ull, 0x9952fbed5a151440ull,
|
||||
0xafe609c313b41e44ull, 0xf111821fa2bca416ull, 0x91bac974fb1264b4ull,
|
||||
0x8e48ff35d6c7d6abull, 0xc4a656654419bd43ull, 0x33554c36685e5510ull,
|
||||
0x0dbd21feab498697ull, 0x982da4663cfe491dull, 0x9e110c7bcbea4ca7ull,
|
||||
0x5fc5a04779c56b8aull, 0x1aa9f44484d80e2eull, 0x6a57b1ab730f203cull,
|
||||
0x87a7dc62d752f7a6ull, 0x40660460944545ffull, 0xc9ac375d77c1a42full,
|
||||
0x744695f0e866d7efull, 0xa1fc6b9681428c85ull, 0x7bf03c19d7917c7bull,
|
||||
0x5715f7915b33eb41ull, 0xdb0708fd8f6cae5full, 0x785ce6b7b125ac8eull,
|
||||
0x6f46eadb56c6815bull, 0x195355d84eeebeeeull, 0x9d7389c0a244de3cull,
|
||||
0xcf99d01953761abdull, 0x0d76ce39de9ec24bull, 0x2e55ecee70beb181ull,
|
||||
0xf56d9d4bd5f86079ull, 0x13ef5a83fb8886fbull, 0x3f3389a4408f43c5ull,
|
||||
0x58ccf45cfad37943ull, 0x415c7f3ef82df846ull, 0x8b3d5cf42915e818ull,
|
||||
0xf8dbb57a6a445f27ull, 0x8ad803ecca8f0070ull, 0x038f9245b2e87c34ull,
|
||||
0xc7c9dee0bedd8a6cull, 0x2ad3fa140eac7d56ull, 0xf775677ce0de0840ull,
|
||||
0x92be221ef1bd0ad5ull, 0xce9d04a487fa1fb9ull, 0x3f6f7024d2c36fa9ull,
|
||||
0x907855eeb028af62ull, 0x4efac5dcd83e49d6ull, 0x77cd8c6be7151aabull,
|
||||
0x0af908b40a753b7dull, 0xe50f30278c983623ull, 0x1d08e2d694222771ull,
|
||||
0xf2ee5ca6f7e928e6ull, 0x11eb962b1b61b93cull, 0xce2bcba19648b21cull,
|
||||
0x7bbebe3034f77154ull, 0x8ce329ace526a319ull, 0xb5dc53d5de4a74d2ull,
|
||||
0x000000000009e8b3ull,
|
||||
|
||||
# define TENS_P12_IDX (TENS_P11_IDX + TENS_P11_SIZE)
|
||||
# define TENS_P12_SIZE 214
|
||||
[TENS_P12_IDX] = 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0x0000000000000000ull, 0x0000000000000000ull, 0x0000000000000000ull,
|
||||
0xd4724e8d2a67c001ull, 0xf89a1e908efe7ae7ull, 0x54e05154ef084117ull,
|
||||
0x506be82913b1bb51ull, 0xe599574efb29b172ull, 0x806c0ed3f0da6146ull,
|
||||
0x45155e93b86ae5beull, 0x7e1e7c34c0591cc2ull, 0x1d1f4cce7c4823daull,
|
||||
0xd6bfdf759b8ba1e8ull, 0xc2dfae78e341be10ull, 0x0f237f1a016b67b2ull,
|
||||
0xaf6a25743dbeabcdull, 0x142e0e80cab3e6d7ull, 0x2c23481161959127ull,
|
||||
0xcb4bf98287009701ull, 0x88052f8cf8169c84ull, 0xbc13176168dde6d4ull,
|
||||
0x54ab9c41ff0b0905ull, 0x1a1c304e7613b224ull, 0x441c2d473bfe167bull,
|
||||
0x78f061814f6cea9cull, 0x30c7ae41eb659fb8ull, 0xa1ebcad7947e0d0eull,
|
||||
0x2130504dd97d9556ull, 0xf2acd5071a8309cbull, 0xfd82373a3f8ec72aull,
|
||||
0x280f4d3295a842bcull, 0x811a4f04f3618ac0ull, 0xd3967a1b6dc3a5b4ull,
|
||||
0xdcfe388f15b8c898ull, 0x8738b909454eb2a0ull, 0x2bd9cc1110c4e996ull,
|
||||
0x655fec303297cd0cull, 0xf4090ee8ae0725b1ull, 0x398c6fed037d19eeull,
|
||||
0xc994a4503b9af26bull, 0x75a697b2b5341743ull, 0x3ccb5b92ac50b9c1ull,
|
||||
0xa8329761ffe06205ull, 0xeb83cadbdfea5242ull, 0x3c20ee69e79dadf7ull,
|
||||
0x7021b97a1e0a6817ull, 0x176ca776743074faull, 0xeca19beb77fb8af6ull,
|
||||
0xaf63b71292baf1deull, 0xa4eb8f8cde35c88bull, 0x40b464a0e137d5e9ull,
|
||||
0x42923bbd87d1cde8ull, 0x2e2690f3cd8f62ffull, 0x59c89f1b095edc16ull,
|
||||
0x5138753d1fa8fd5dull, 0x80152f18390a2b29ull, 0xf984d83e2dd8d925ull,
|
||||
0xc19e1faf7a872e74ull, 0xecf9b5d0ed4d542dull, 0xc53c0adf9462ea75ull,
|
||||
0x37a2d4390caea134ull, 0x2181327ec8fa2e8aull, 0x2d2408206e7bb827ull,
|
||||
0x5893d4b850be10e0ull, 0x1f2b2322ab312bb9ull, 0xbf627ede440b3f25ull,
|
||||
0xb608b89572dac789ull, 0x86deb3f078787e2aull, 0xbb9373f46fee7aabull,
|
||||
0xf7d8b57e27ecf57bull, 0x3d04e8d2fca26a9full, 0x3172826ac9df13cbull,
|
||||
0xa8fcd8e0cd9e8d7cull, 0x307641d9b2c39497ull, 0x2608c4cf1cc939c1ull,
|
||||
0x3d326a7eb6d1c7bfull, 0x8e13e25feeaf19e6ull, 0x2dfe6d97ee63302bull,
|
||||
0xe41d3cc425971d58ull, 0xab8db59a0a80627cull, 0xe90afb779eea37c8ull,
|
||||
0x9ee3352c90ca19cfull, 0xfe78d6823613c850ull, 0x5b060904788f6e50ull,
|
||||
0x3fecb534b71bd1a4ull, 0x20c33857b32c450cull, 0x0239f4cea6e9cfdaull,
|
||||
0xa19adb9548497187ull, 0x95aca6a8b492ed8aull, 0xcf1b23504dcd6cd9ull,
|
||||
0x1a67778cfbe8b12aull, 0xc32da38338eb3accull, 0xa03f40a8fb126ab1ull,
|
||||
0xe9ce4724ed5bf546ull, 0x73a130d84c4a74fdull, 0xa2ebd6c1d9960e2dull,
|
||||
0x6f233b7c94ab6febull, 0x8e7b9a7349126080ull, 0xd298f9994b8c9091ull,
|
||||
0xa96ddeff35e836b5ull, 0x6b0dd9bc96119b31ull, 0x282566fbc6cc3f8dull,
|
||||
0xd6769f3b72b882e7ull, 0x00fc509ba674343dull, 0xd6266a3fdcbf7789ull,
|
||||
0x4e89541bae9641fdull, 0x53400d0311953407ull, 0xe5b533458e0dd75aull,
|
||||
0x108b89bc108f19adull, 0xe03b2b6341a4c954ull, 0x97aced8e437b3d7full,
|
||||
0x2c5508c2cbd66670ull, 0x5c4f2ef0650ebc69ull, 0x9985a2df904ff6bfull,
|
||||
0x5ed8d2399faddd9eull, 0xe3e51cb925585832ull, 0x56c02d9a0ff4f1d4ull,
|
||||
0xc1a08a138c4ef804ull, 0xe6d2767113fd01c8ull, 0x9d0176cca7c234f4ull,
|
||||
0x4d8bfa89d0d73df2ull, 0x2b17e0b2544f10cdull, 0xfd86fe49b70a5c7dull,
|
||||
0x214495bbdf373f41ull, 0x00d313d584e857fdull, 0xa4ba47440496fcbeull,
|
||||
0xaec29e6ee8cac982ull, 0x7000a51987ec7038ull, 0xff66e42caeee333bull,
|
||||
0x03b4f63b8afd6b25ull, 0x5ab8d9c7bd7991dcull, 0x48741a6c2ed4684eull,
|
||||
0x2fdc6349af06940dull, 0xe974996fb03d7ecdull, 0x52ec8721ac7867f9ull,
|
||||
0x8edd2d00bcdd9d4aull, 0x41c759f83557de06ull, 0xa75409f23956d4b9ull,
|
||||
0xb6100fab123cd8a1ull, 0x2e8d623b3e7b21e2ull, 0xbca35f7792959da2ull,
|
||||
0x35fcb457200c03a5ull, 0xf74eb9281bb6c6e4ull, 0x87cc1d213d5d0b54ull,
|
||||
0x18ae42404964046full, 0x8bd2b496d868b275ull, 0xc234d8f51c5563f4ull,
|
||||
0xf9151ffff868e970ull, 0x271133eeae7be4a2ull, 0x25254932bb0fd922ull,
|
||||
0x104bcd64a60a9fc0ull, 0x0000006230290145ull
|
||||
#endif
|
||||
};
|
||||
|
||||
#else
|
||||
# error "mp_limb_t size " BITS_PER_MP_LIMB "not accounted for"
|
||||
#endif
|
||||
|
||||
/* Each of array variable above defines one mpn integer which is a power of 10.
|
||||
This table points to those variables, indexed by the exponent. */
|
||||
|
||||
const struct mp_power _fpioconst_pow10[FLT128_MAX_10_EXP_LOG + 1] =
|
||||
{
|
||||
{ TENS_P0_IDX, TENS_P0_SIZE, 4, },
|
||||
{ TENS_P1_IDX, TENS_P1_SIZE, 7, 4 },
|
||||
{ TENS_P2_IDX, TENS_P2_SIZE, 14, 10 },
|
||||
{ TENS_P3_IDX, TENS_P3_SIZE, 27, 24 },
|
||||
{ TENS_P4_IDX, TENS_P4_SIZE, 54, 50 },
|
||||
{ TENS_P5_IDX, TENS_P5_SIZE, 107, 103 },
|
||||
{ TENS_P6_IDX, TENS_P6_SIZE, 213, 210 },
|
||||
{ TENS_P7_IDX, TENS_P7_SIZE, 426, 422 },
|
||||
{ TENS_P8_IDX, TENS_P8_SIZE, 851, 848 },
|
||||
#if FLT128_MAX_EXP > 1024
|
||||
{ TENS_P9_IDX, TENS_P9_SIZE, 1701, 1698 },
|
||||
{ TENS_P10_IDX, TENS_P10_SIZE, 3402, 3399 },
|
||||
{ TENS_P11_IDX, TENS_P11_SIZE, 6804, 6800 },
|
||||
{ TENS_P12_IDX, TENS_P12_SIZE, 13607, 13604 }
|
||||
#endif
|
||||
};
|
||||
|
||||
#if LAST_POW10 > _LAST_POW10
|
||||
# error "Need to expand 10^(2^i) table for i up to" LAST_POW10
|
||||
#endif
|
64
libquadmath/printf/fpioconst.h
Normal file
64
libquadmath/printf/fpioconst.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* Header file for constants used in floating point <-> decimal conversions.
|
||||
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _FPIOCONST_H
|
||||
#define _FPIOCONST_H
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/* These values are used by __printf_fp, where they are noncritical (if the
|
||||
value is not large enough, it will just be slower); and by
|
||||
strtof/strtod/strtold, where it is critical (it's used for overflow
|
||||
detection).
|
||||
|
||||
XXX These should be defined in <float.h>. For the time being, we have the
|
||||
IEEE754 values here. */
|
||||
|
||||
#define FLT128_MAX_10_EXP_LOG 12 /* = floor(log_2(FLT128_MAX_10_EXP)) */
|
||||
|
||||
|
||||
/* The array with the number representation. */
|
||||
#define __tens __quadmath_tens
|
||||
extern const mp_limb_t __tens[] attribute_hidden;
|
||||
|
||||
/* Table of powers of ten. This is used by __printf_fp and by
|
||||
strtof/strtod/strtold. */
|
||||
struct mp_power
|
||||
{
|
||||
size_t arrayoff; /* Offset in `__tens'. */
|
||||
mp_size_t arraysize; /* Size of the array. */
|
||||
int p_expo; /* Exponent of the number 10^(2^i). */
|
||||
int m_expo; /* Exponent of the number 10^-(2^i-1). */
|
||||
};
|
||||
#define _fpioconst_pow10 __quadmath_fpioconst_pow10
|
||||
extern const struct mp_power _fpioconst_pow10[FLT128_MAX_10_EXP_LOG + 1]
|
||||
attribute_hidden;
|
||||
|
||||
/* The constants in the array `_fpioconst_pow10' have an offset. */
|
||||
#if BITS_PER_MP_LIMB == 32
|
||||
# define _FPIO_CONST_OFFSET 2
|
||||
#else
|
||||
# define _FPIO_CONST_OFFSET 1
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* fpioconst.h */
|
177
libquadmath/printf/gmp-impl.h
Normal file
177
libquadmath/printf/gmp-impl.h
Normal file
@ -0,0 +1,177 @@
|
||||
/* Include file for internal GNU MP types and definitions.
|
||||
|
||||
Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "quadmath-imp.h"
|
||||
|
||||
#undef alloca
|
||||
#define alloca __builtin_alloca
|
||||
|
||||
#define ABS(x) (x >= 0 ? x : -x)
|
||||
#ifndef MIN
|
||||
#define MIN(l,o) ((l) < (o) ? (l) : (o))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(h,i) ((h) > (i) ? (h) : (i))
|
||||
#endif
|
||||
|
||||
#define BITS_PER_MP_LIMB (__SIZEOF_LONG__ * __CHAR_BIT__)
|
||||
#define BYTES_PER_MP_LIMB (BITS_PER_MP_LIMB / __CHAR_BIT__)
|
||||
typedef unsigned long int mp_limb_t;
|
||||
typedef long int mp_limb_signed_t;
|
||||
|
||||
typedef mp_limb_t * mp_ptr;
|
||||
typedef const mp_limb_t * mp_srcptr;
|
||||
typedef long int mp_size_t;
|
||||
typedef long int mp_exp_t;
|
||||
|
||||
/* Define stuff for longlong.h. */
|
||||
typedef unsigned int UQItype __attribute__ ((mode (QI)));
|
||||
typedef int SItype __attribute__ ((mode (SI)));
|
||||
typedef unsigned int USItype __attribute__ ((mode (SI)));
|
||||
typedef int DItype __attribute__ ((mode (DI)));
|
||||
typedef unsigned int UDItype __attribute__ ((mode (DI)));
|
||||
|
||||
typedef mp_limb_t UWtype;
|
||||
typedef unsigned int UHWtype;
|
||||
#define W_TYPE_SIZE BITS_PER_MP_LIMB
|
||||
|
||||
#ifdef HAVE_HIDDEN_VISIBILITY
|
||||
#define attribute_hidden __attribute__((__visibility__ ("hidden")))
|
||||
#else
|
||||
#define attribute_hidden
|
||||
#endif
|
||||
|
||||
#include "../../gcc/longlong.h"
|
||||
|
||||
/* Copy NLIMBS *limbs* from SRC to DST. */
|
||||
#define MPN_COPY_INCR(DST, SRC, NLIMBS) \
|
||||
do { \
|
||||
mp_size_t __i; \
|
||||
for (__i = 0; __i < (NLIMBS); __i++) \
|
||||
(DST)[__i] = (SRC)[__i]; \
|
||||
} while (0)
|
||||
#define MPN_COPY_DECR(DST, SRC, NLIMBS) \
|
||||
do { \
|
||||
mp_size_t __i; \
|
||||
for (__i = (NLIMBS) - 1; __i >= 0; __i--) \
|
||||
(DST)[__i] = (SRC)[__i]; \
|
||||
} while (0)
|
||||
#define MPN_COPY MPN_COPY_INCR
|
||||
|
||||
/* Zero NLIMBS *limbs* AT DST. */
|
||||
#define MPN_ZERO(DST, NLIMBS) \
|
||||
do { \
|
||||
mp_size_t __i; \
|
||||
for (__i = 0; __i < (NLIMBS); __i++) \
|
||||
(DST)[__i] = 0; \
|
||||
} while (0)
|
||||
|
||||
#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
|
||||
do { \
|
||||
if ((size) < KARATSUBA_THRESHOLD) \
|
||||
impn_mul_n_basecase (prodp, up, vp, size); \
|
||||
else \
|
||||
impn_mul_n (prodp, up, vp, size, tspace); \
|
||||
} while (0);
|
||||
|
||||
#define __MPN(x) __quadmath_mpn_##x
|
||||
|
||||
/* Internal mpn calls */
|
||||
#define impn_mul_n_basecase __MPN(impn_mul_n_basecase)
|
||||
#define impn_mul_n __MPN(impn_mul_n)
|
||||
|
||||
/* Prototypes for internal mpn calls. */
|
||||
void impn_mul_n_basecase (mp_ptr prodp, mp_srcptr up, mp_srcptr vp,
|
||||
mp_size_t size) attribute_hidden;
|
||||
void impn_mul_n (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size,
|
||||
mp_ptr tspace) attribute_hidden;
|
||||
|
||||
#define mpn_add_n __MPN(add_n)
|
||||
#define mpn_addmul_1 __MPN(addmul_1)
|
||||
#define mpn_cmp __MPN(cmp)
|
||||
#define mpn_divrem __MPN(divrem)
|
||||
#define mpn_lshift __MPN(lshift)
|
||||
#define mpn_mul __MPN(mul)
|
||||
#define mpn_mul_1 __MPN(mul_1)
|
||||
#define mpn_rshift __MPN(rshift)
|
||||
#define mpn_sub_n __MPN(sub_n)
|
||||
#define mpn_submul_1 __MPN(submul_1)
|
||||
|
||||
mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_addmul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
|
||||
attribute_hidden;
|
||||
int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t) attribute_hidden;
|
||||
mp_limb_t mpn_divrem (mp_ptr, mp_size_t, mp_ptr, mp_size_t, mp_srcptr,
|
||||
mp_size_t) attribute_hidden;
|
||||
mp_limb_t mpn_lshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_mul (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_mul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_rshift (mp_ptr, mp_srcptr, mp_size_t, unsigned int)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t)
|
||||
attribute_hidden;
|
||||
mp_limb_t mpn_submul_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t)
|
||||
attribute_hidden;
|
||||
|
||||
#define mpn_extract_flt128 __MPN(extract_flt128)
|
||||
mp_size_t mpn_extract_flt128 (mp_ptr res_ptr, mp_size_t size, int *expt,
|
||||
int *is_neg, __float128 value) attribute_hidden;
|
||||
|
||||
#define mpn_divmod(qp,np,nsize,dp,dsize) mpn_divrem (qp,0,np,nsize,dp,dsize)
|
||||
|
||||
static inline mp_limb_t
|
||||
mpn_add_1 (register mp_ptr res_ptr,
|
||||
register mp_srcptr s1_ptr,
|
||||
register mp_size_t s1_size,
|
||||
register mp_limb_t s2_limb)
|
||||
{
|
||||
register mp_limb_t x;
|
||||
|
||||
x = *s1_ptr++;
|
||||
s2_limb = x + s2_limb;
|
||||
*res_ptr++ = s2_limb;
|
||||
if (s2_limb < x)
|
||||
{
|
||||
while (--s1_size != 0)
|
||||
{
|
||||
x = *s1_ptr++ + 1;
|
||||
*res_ptr++ = x;
|
||||
if (x != 0)
|
||||
goto fin;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
fin:
|
||||
if (res_ptr != s1_ptr)
|
||||
{
|
||||
mp_size_t i;
|
||||
for (i = 0; i < s1_size - 1; i++)
|
||||
res_ptr[i] = s1_ptr[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
86
libquadmath/printf/lshift.c
Normal file
86
libquadmath/printf/lshift.c
Normal file
@ -0,0 +1,86 @@
|
||||
/* mpn_lshift -- Shift left low level.
|
||||
|
||||
Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
|
||||
and store the USIZE least significant digits of the result at WP.
|
||||
Return the bits shifted out from the most significant digit.
|
||||
|
||||
Argument constraints:
|
||||
1. 0 < CNT < BITS_PER_MP_LIMB
|
||||
2. If the result is to be written over the input, WP must be >= UP.
|
||||
*/
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_lshift (register mp_ptr wp,
|
||||
register mp_srcptr up, mp_size_t usize,
|
||||
register unsigned int cnt)
|
||||
#else
|
||||
mpn_lshift (wp, up, usize, cnt)
|
||||
register mp_ptr wp;
|
||||
register mp_srcptr up;
|
||||
mp_size_t usize;
|
||||
register unsigned int cnt;
|
||||
#endif
|
||||
{
|
||||
register mp_limb_t high_limb, low_limb;
|
||||
register unsigned sh_1, sh_2;
|
||||
register mp_size_t i;
|
||||
mp_limb_t retval;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (usize == 0 || cnt == 0)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
sh_1 = cnt;
|
||||
#if 0
|
||||
if (sh_1 == 0)
|
||||
{
|
||||
if (wp != up)
|
||||
{
|
||||
/* Copy from high end to low end, to allow specified input/output
|
||||
overlapping. */
|
||||
for (i = usize - 1; i >= 0; i--)
|
||||
wp[i] = up[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
wp += 1;
|
||||
sh_2 = BITS_PER_MP_LIMB - sh_1;
|
||||
i = usize - 1;
|
||||
low_limb = up[i];
|
||||
retval = low_limb >> sh_2;
|
||||
high_limb = low_limb;
|
||||
while (--i >= 0)
|
||||
{
|
||||
low_limb = up[i];
|
||||
wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
|
||||
high_limb = low_limb;
|
||||
}
|
||||
wp[i] = high_limb << sh_1;
|
||||
|
||||
return retval;
|
||||
}
|
147
libquadmath/printf/mul.c
Normal file
147
libquadmath/printf/mul.c
Normal file
@ -0,0 +1,147 @@
|
||||
/* mpn_mul -- Multiply two natural numbers.
|
||||
|
||||
Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
|
||||
and v (pointed to by VP, with VSIZE limbs), and store the result at
|
||||
PRODP. USIZE + VSIZE limbs are always stored, but if the input
|
||||
operands are normalized. Return the most significant limb of the
|
||||
result.
|
||||
|
||||
NOTE: The space pointed to by PRODP is overwritten before finished
|
||||
with U and V, so overlap is an error.
|
||||
|
||||
Argument constraints:
|
||||
1. USIZE >= VSIZE.
|
||||
2. PRODP != UP and PRODP != VP, i.e. the destination
|
||||
must be distinct from the multiplier and the multiplicand. */
|
||||
|
||||
/* If KARATSUBA_THRESHOLD is not already defined, define it to a
|
||||
value which is good on most machines. */
|
||||
#ifndef KARATSUBA_THRESHOLD
|
||||
#define KARATSUBA_THRESHOLD 32
|
||||
#endif
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_mul (mp_ptr prodp,
|
||||
mp_srcptr up, mp_size_t usize,
|
||||
mp_srcptr vp, mp_size_t vsize)
|
||||
#else
|
||||
mpn_mul (prodp, up, usize, vp, vsize)
|
||||
mp_ptr prodp;
|
||||
mp_srcptr up;
|
||||
mp_size_t usize;
|
||||
mp_srcptr vp;
|
||||
mp_size_t vsize;
|
||||
#endif
|
||||
{
|
||||
mp_ptr prod_endp = prodp + usize + vsize - 1;
|
||||
mp_limb_t cy;
|
||||
mp_ptr tspace;
|
||||
|
||||
if (vsize < KARATSUBA_THRESHOLD)
|
||||
{
|
||||
/* Handle simple cases with traditional multiplication.
|
||||
|
||||
This is the most critical code of the entire function. All
|
||||
multiplies rely on this, both small and huge. Small ones arrive
|
||||
here immediately. Huge ones arrive here as this is the base case
|
||||
for Karatsuba's recursive algorithm below. */
|
||||
mp_size_t i;
|
||||
mp_limb_t cy_limb;
|
||||
mp_limb_t v_limb;
|
||||
|
||||
if (vsize == 0)
|
||||
return 0;
|
||||
|
||||
/* Multiply by the first limb in V separately, as the result can be
|
||||
stored (not added) to PROD. We also avoid a loop for zeroing. */
|
||||
v_limb = vp[0];
|
||||
if (v_limb <= 1)
|
||||
{
|
||||
if (v_limb == 1)
|
||||
MPN_COPY (prodp, up, usize);
|
||||
else
|
||||
MPN_ZERO (prodp, usize);
|
||||
cy_limb = 0;
|
||||
}
|
||||
else
|
||||
cy_limb = mpn_mul_1 (prodp, up, usize, v_limb);
|
||||
|
||||
prodp[usize] = cy_limb;
|
||||
prodp++;
|
||||
|
||||
/* For each iteration in the outer loop, multiply one limb from
|
||||
U with one limb from V, and add it to PROD. */
|
||||
for (i = 1; i < vsize; i++)
|
||||
{
|
||||
v_limb = vp[i];
|
||||
if (v_limb <= 1)
|
||||
{
|
||||
cy_limb = 0;
|
||||
if (v_limb == 1)
|
||||
cy_limb = mpn_add_n (prodp, prodp, up, usize);
|
||||
}
|
||||
else
|
||||
cy_limb = mpn_addmul_1 (prodp, up, usize, v_limb);
|
||||
|
||||
prodp[usize] = cy_limb;
|
||||
prodp++;
|
||||
}
|
||||
return cy_limb;
|
||||
}
|
||||
|
||||
tspace = (mp_ptr) alloca (2 * vsize * BYTES_PER_MP_LIMB);
|
||||
MPN_MUL_N_RECURSE (prodp, up, vp, vsize, tspace);
|
||||
|
||||
prodp += vsize;
|
||||
up += vsize;
|
||||
usize -= vsize;
|
||||
if (usize >= vsize)
|
||||
{
|
||||
mp_ptr tp = (mp_ptr) alloca (2 * vsize * BYTES_PER_MP_LIMB);
|
||||
do
|
||||
{
|
||||
MPN_MUL_N_RECURSE (tp, up, vp, vsize, tspace);
|
||||
cy = mpn_add_n (prodp, prodp, tp, vsize);
|
||||
mpn_add_1 (prodp + vsize, tp + vsize, vsize, cy);
|
||||
prodp += vsize;
|
||||
up += vsize;
|
||||
usize -= vsize;
|
||||
}
|
||||
while (usize >= vsize);
|
||||
}
|
||||
|
||||
/* True: usize < vsize. */
|
||||
|
||||
/* Make life simple: Recurse. */
|
||||
|
||||
if (usize != 0)
|
||||
{
|
||||
mpn_mul (tspace, vp, vsize, up, usize);
|
||||
cy = mpn_add_n (prodp, prodp, tspace, vsize);
|
||||
mpn_add_1 (prodp + vsize, tspace + vsize, usize, cy);
|
||||
}
|
||||
|
||||
return *prod_endp;
|
||||
}
|
57
libquadmath/printf/mul_1.c
Normal file
57
libquadmath/printf/mul_1.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* mpn_mul_1 -- Multiply a limb vector with a single limb and
|
||||
store the product in a second limb vector.
|
||||
|
||||
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
mp_limb_t
|
||||
mpn_mul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
|
||||
register mp_ptr res_ptr;
|
||||
register mp_srcptr s1_ptr;
|
||||
mp_size_t s1_size;
|
||||
register mp_limb_t s2_limb;
|
||||
{
|
||||
register mp_limb_t cy_limb;
|
||||
register mp_size_t j;
|
||||
register mp_limb_t prod_high, prod_low;
|
||||
|
||||
/* The loop counter and index J goes from -S1_SIZE to -1. This way
|
||||
the loop becomes faster. */
|
||||
j = -s1_size;
|
||||
|
||||
/* Offset the base pointers to compensate for the negative indices. */
|
||||
s1_ptr -= j;
|
||||
res_ptr -= j;
|
||||
|
||||
cy_limb = 0;
|
||||
do
|
||||
{
|
||||
umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
|
||||
|
||||
prod_low += cy_limb;
|
||||
cy_limb = (prod_low < cy_limb) + prod_high;
|
||||
|
||||
res_ptr[j] = prod_low;
|
||||
}
|
||||
while (++j != 0);
|
||||
|
||||
return cy_limb;
|
||||
}
|
219
libquadmath/printf/mul_n.c
Normal file
219
libquadmath/printf/mul_n.c
Normal file
@ -0,0 +1,219 @@
|
||||
/* mpn_mul_n -- Multiply two natural numbers of length n.
|
||||
|
||||
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
|
||||
both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
|
||||
always stored. Return the most significant limb.
|
||||
|
||||
Argument constraints:
|
||||
1. PRODP != UP and PRODP != VP, i.e. the destination
|
||||
must be distinct from the multiplier and the multiplicand. */
|
||||
|
||||
/* If KARATSUBA_THRESHOLD is not already defined, define it to a
|
||||
value which is good on most machines. */
|
||||
#ifndef KARATSUBA_THRESHOLD
|
||||
#define KARATSUBA_THRESHOLD 32
|
||||
#endif
|
||||
|
||||
/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
|
||||
#if KARATSUBA_THRESHOLD < 2
|
||||
#undef KARATSUBA_THRESHOLD
|
||||
#define KARATSUBA_THRESHOLD 2
|
||||
#endif
|
||||
|
||||
/* Handle simple cases with traditional multiplication.
|
||||
|
||||
This is the most critical code of multiplication. All multiplies rely
|
||||
on this, both small and huge. Small ones arrive here immediately. Huge
|
||||
ones arrive here as this is the base case for Karatsuba's recursive
|
||||
algorithm below. */
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
impn_mul_n_basecase (mp_ptr prodp, mp_srcptr up, mp_srcptr vp, mp_size_t size)
|
||||
#else
|
||||
impn_mul_n_basecase (prodp, up, vp, size)
|
||||
mp_ptr prodp;
|
||||
mp_srcptr up;
|
||||
mp_srcptr vp;
|
||||
mp_size_t size;
|
||||
#endif
|
||||
{
|
||||
mp_size_t i;
|
||||
mp_limb_t cy_limb;
|
||||
mp_limb_t v_limb;
|
||||
|
||||
/* Multiply by the first limb in V separately, as the result can be
|
||||
stored (not added) to PROD. We also avoid a loop for zeroing. */
|
||||
v_limb = vp[0];
|
||||
if (v_limb <= 1)
|
||||
{
|
||||
if (v_limb == 1)
|
||||
MPN_COPY (prodp, up, size);
|
||||
else
|
||||
MPN_ZERO (prodp, size);
|
||||
cy_limb = 0;
|
||||
}
|
||||
else
|
||||
cy_limb = mpn_mul_1 (prodp, up, size, v_limb);
|
||||
|
||||
prodp[size] = cy_limb;
|
||||
prodp++;
|
||||
|
||||
/* For each iteration in the outer loop, multiply one limb from
|
||||
U with one limb from V, and add it to PROD. */
|
||||
for (i = 1; i < size; i++)
|
||||
{
|
||||
v_limb = vp[i];
|
||||
if (v_limb <= 1)
|
||||
{
|
||||
cy_limb = 0;
|
||||
if (v_limb == 1)
|
||||
cy_limb = mpn_add_n (prodp, prodp, up, size);
|
||||
}
|
||||
else
|
||||
cy_limb = mpn_addmul_1 (prodp, up, size, v_limb);
|
||||
|
||||
prodp[size] = cy_limb;
|
||||
prodp++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
impn_mul_n (mp_ptr prodp,
|
||||
mp_srcptr up, mp_srcptr vp, mp_size_t size, mp_ptr tspace)
|
||||
#else
|
||||
impn_mul_n (prodp, up, vp, size, tspace)
|
||||
mp_ptr prodp;
|
||||
mp_srcptr up;
|
||||
mp_srcptr vp;
|
||||
mp_size_t size;
|
||||
mp_ptr tspace;
|
||||
#endif
|
||||
{
|
||||
if ((size & 1) != 0)
|
||||
{
|
||||
/* The size is odd, the code code below doesn't handle that.
|
||||
Multiply the least significant (size - 1) limbs with a recursive
|
||||
call, and handle the most significant limb of S1 and S2
|
||||
separately. */
|
||||
/* A slightly faster way to do this would be to make the Karatsuba
|
||||
code below behave as if the size were even, and let it check for
|
||||
odd size in the end. I.e., in essence move this code to the end.
|
||||
Doing so would save us a recursive call, and potentially make the
|
||||
stack grow a lot less. */
|
||||
|
||||
mp_size_t esize = size - 1; /* even size */
|
||||
mp_limb_t cy_limb;
|
||||
|
||||
MPN_MUL_N_RECURSE (prodp, up, vp, esize, tspace);
|
||||
cy_limb = mpn_addmul_1 (prodp + esize, up, esize, vp[esize]);
|
||||
prodp[esize + esize] = cy_limb;
|
||||
cy_limb = mpn_addmul_1 (prodp + esize, vp, size, up[esize]);
|
||||
|
||||
prodp[esize + size] = cy_limb;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
|
||||
|
||||
Split U in two pieces, U1 and U0, such that
|
||||
U = U0 + U1*(B**n),
|
||||
and V in V1 and V0, such that
|
||||
V = V0 + V1*(B**n).
|
||||
|
||||
UV is then computed recursively using the identity
|
||||
|
||||
2n n n n
|
||||
UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
|
||||
1 1 1 0 0 1 0 0
|
||||
|
||||
Where B = 2**BITS_PER_MP_LIMB. */
|
||||
|
||||
mp_size_t hsize = size >> 1;
|
||||
mp_limb_t cy;
|
||||
int negflg;
|
||||
|
||||
/*** Product H. ________________ ________________
|
||||
|_____U1 x V1____||____U0 x V0_____| */
|
||||
/* Put result in upper part of PROD and pass low part of TSPACE
|
||||
as new TSPACE. */
|
||||
MPN_MUL_N_RECURSE (prodp + size, up + hsize, vp + hsize, hsize, tspace);
|
||||
|
||||
/*** Product M. ________________
|
||||
|_(U1-U0)(V0-V1)_| */
|
||||
if (mpn_cmp (up + hsize, up, hsize) >= 0)
|
||||
{
|
||||
mpn_sub_n (prodp, up + hsize, up, hsize);
|
||||
negflg = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpn_sub_n (prodp, up, up + hsize, hsize);
|
||||
negflg = 1;
|
||||
}
|
||||
if (mpn_cmp (vp + hsize, vp, hsize) >= 0)
|
||||
{
|
||||
mpn_sub_n (prodp + hsize, vp + hsize, vp, hsize);
|
||||
negflg ^= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mpn_sub_n (prodp + hsize, vp, vp + hsize, hsize);
|
||||
/* No change of NEGFLG. */
|
||||
}
|
||||
/* Read temporary operands from low part of PROD.
|
||||
Put result in low part of TSPACE using upper part of TSPACE
|
||||
as new TSPACE. */
|
||||
MPN_MUL_N_RECURSE (tspace, prodp, prodp + hsize, hsize, tspace + size);
|
||||
|
||||
/*** Add/copy product H. */
|
||||
MPN_COPY (prodp + hsize, prodp + size, hsize);
|
||||
cy = mpn_add_n (prodp + size, prodp + size, prodp + size + hsize, hsize);
|
||||
|
||||
/*** Add product M (if NEGFLG M is a negative number). */
|
||||
if (negflg)
|
||||
cy -= mpn_sub_n (prodp + hsize, prodp + hsize, tspace, size);
|
||||
else
|
||||
cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size);
|
||||
|
||||
/*** Product L. ________________ ________________
|
||||
|________________||____U0 x V0_____| */
|
||||
/* Read temporary operands from low part of PROD.
|
||||
Put result in low part of TSPACE using upper part of TSPACE
|
||||
as new TSPACE. */
|
||||
MPN_MUL_N_RECURSE (tspace, up, vp, hsize, tspace + size);
|
||||
|
||||
/*** Add/copy Product L (twice). */
|
||||
|
||||
cy += mpn_add_n (prodp + hsize, prodp + hsize, tspace, size);
|
||||
if (cy)
|
||||
mpn_add_1 (prodp + hsize + size, prodp + hsize + size, hsize, cy);
|
||||
|
||||
MPN_COPY (prodp, tspace, hsize);
|
||||
cy = mpn_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
|
||||
if (cy)
|
||||
mpn_add_1 (prodp + size, prodp + size, size, 1);
|
||||
}
|
||||
}
|
1244
libquadmath/printf/printf_fp.c
Normal file
1244
libquadmath/printf/printf_fp.c
Normal file
File diff suppressed because it is too large
Load Diff
444
libquadmath/printf/printf_fphex.c
Normal file
444
libquadmath/printf/printf_fphex.c
Normal file
@ -0,0 +1,444 @@
|
||||
/* Print floating point number in hexadecimal notation according to ISO C99.
|
||||
Copyright (C) 1997-2002,2004,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define NDEBUG
|
||||
#include <assert.h>
|
||||
#include "quadmath-printf.h"
|
||||
#include "_itoa.h"
|
||||
#include "_itowa.h"
|
||||
|
||||
|
||||
/* Macros for doing the actual output. */
|
||||
|
||||
#define outchar(ch) \
|
||||
do \
|
||||
{ \
|
||||
register const int outc = (ch); \
|
||||
if (PUTC (outc, fp) == EOF) \
|
||||
return -1; \
|
||||
++done; \
|
||||
} while (0)
|
||||
|
||||
#define PRINT(ptr, wptr, len) \
|
||||
do \
|
||||
{ \
|
||||
register size_t outlen = (len); \
|
||||
if (wide) \
|
||||
while (outlen-- > 0) \
|
||||
outchar (*wptr++); \
|
||||
else \
|
||||
while (outlen-- > 0) \
|
||||
outchar (*ptr++); \
|
||||
} while (0)
|
||||
|
||||
#define PADN(ch, len) \
|
||||
do \
|
||||
{ \
|
||||
if (PAD (fp, ch, len) != len) \
|
||||
return -1; \
|
||||
done += len; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
|
||||
int
|
||||
__quadmath_printf_fphex (struct __quadmath_printf_file *fp,
|
||||
const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
/* The floating-point value to output. */
|
||||
ieee854_float128 fpnum;
|
||||
|
||||
/* Locale-dependent representation of decimal point. */
|
||||
const char *decimal;
|
||||
wchar_t decimalwc;
|
||||
|
||||
/* "NaN" or "Inf" for the special cases. */
|
||||
const char *special = NULL;
|
||||
const wchar_t *wspecial = NULL;
|
||||
|
||||
/* Buffer for the generated number string for the mantissa. The
|
||||
maximal size for the mantissa is 128 bits. */
|
||||
char numbuf[32];
|
||||
char *numstr;
|
||||
char *numend;
|
||||
wchar_t wnumbuf[32];
|
||||
wchar_t *wnumstr;
|
||||
wchar_t *wnumend;
|
||||
int negative;
|
||||
|
||||
/* The maximal exponent of two in decimal notation has 5 digits. */
|
||||
char expbuf[5];
|
||||
char *expstr;
|
||||
wchar_t wexpbuf[5];
|
||||
wchar_t *wexpstr;
|
||||
int expnegative;
|
||||
int exponent;
|
||||
|
||||
/* Non-zero is mantissa is zero. */
|
||||
int zero_mantissa;
|
||||
|
||||
/* The leading digit before the decimal point. */
|
||||
char leading;
|
||||
|
||||
/* Precision. */
|
||||
int precision = info->prec;
|
||||
|
||||
/* Width. */
|
||||
int width = info->width;
|
||||
|
||||
/* Number of characters written. */
|
||||
int done = 0;
|
||||
|
||||
/* Nonzero if this is output on a wide character stream. */
|
||||
int wide = info->wide;
|
||||
|
||||
/* Figure out the decimal point character. */
|
||||
#ifdef USE_LOCALE_SUPPORT
|
||||
if (info->extra == 0)
|
||||
{
|
||||
decimal = nl_langinfo (DECIMAL_POINT);
|
||||
decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
|
||||
}
|
||||
else
|
||||
{
|
||||
decimal = nl_langinfo (MON_DECIMAL_POINT);
|
||||
if (*decimal == '\0')
|
||||
decimal = nl_langinfo (DECIMAL_POINT);
|
||||
decimalwc = nl_langinfo_wc (_NL_MONETARY_DECIMAL_POINT_WC);
|
||||
if (decimalwc == L'\0')
|
||||
decimalwc = nl_langinfo_wc (_NL_NUMERIC_DECIMAL_POINT_WC);
|
||||
}
|
||||
/* The decimal point character must never be zero. */
|
||||
assert (*decimal != '\0' && decimalwc != L'\0');
|
||||
#else
|
||||
decimal = ".";
|
||||
decimalwc = L_('.');
|
||||
#endif
|
||||
|
||||
/* Fetch the argument value. */
|
||||
{
|
||||
fpnum.value = **(const __float128 **) args[0];
|
||||
|
||||
/* Check for special values: not a number or infinity. */
|
||||
if (isnanq (fpnum.value))
|
||||
{
|
||||
negative = fpnum.ieee.negative != 0;
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "NAN";
|
||||
wspecial = L_("NAN");
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "nan";
|
||||
wspecial = L_("nan");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isinfq (fpnum.value))
|
||||
{
|
||||
if (isupper (info->spec))
|
||||
{
|
||||
special = "INF";
|
||||
wspecial = L_("INF");
|
||||
}
|
||||
else
|
||||
{
|
||||
special = "inf";
|
||||
wspecial = L_("inf");
|
||||
}
|
||||
}
|
||||
|
||||
negative = signbitq (fpnum.value);
|
||||
}
|
||||
}
|
||||
|
||||
if (special)
|
||||
{
|
||||
int width = info->width;
|
||||
|
||||
if (negative || info->showsign || info->space)
|
||||
--width;
|
||||
width -= 3;
|
||||
|
||||
if (!info->left && width > 0)
|
||||
PADN (' ', width);
|
||||
|
||||
if (negative)
|
||||
outchar ('-');
|
||||
else if (info->showsign)
|
||||
outchar ('+');
|
||||
else if (info->space)
|
||||
outchar (' ');
|
||||
|
||||
PRINT (special, wspecial, 3);
|
||||
|
||||
if (info->left && width > 0)
|
||||
PADN (' ', width);
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
{
|
||||
/* We have 112 bits of mantissa plus one implicit digit. Since
|
||||
112 bits are representable without rest using hexadecimal
|
||||
digits we use only the implicit digits for the number before
|
||||
the decimal point. */
|
||||
uint64_t num0, num1;
|
||||
|
||||
assert (sizeof (long double) == 16);
|
||||
|
||||
num0 = fpnum.ieee.mant_high;
|
||||
num1 = fpnum.ieee.mant_low;
|
||||
|
||||
zero_mantissa = (num0|num1) == 0;
|
||||
|
||||
if (sizeof (unsigned long int) > 6)
|
||||
{
|
||||
numstr = _itoa_word (num1, numbuf + sizeof numbuf, 16,
|
||||
info->spec == 'A');
|
||||
wnumstr = _itowa_word (num1,
|
||||
wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
|
||||
16, info->spec == 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
numstr = _itoa (num1, numbuf + sizeof numbuf, 16,
|
||||
info->spec == 'A');
|
||||
wnumstr = _itowa (num1,
|
||||
wnumbuf + sizeof (wnumbuf) / sizeof (wchar_t),
|
||||
16, info->spec == 'A');
|
||||
}
|
||||
|
||||
while (numstr > numbuf + (sizeof numbuf - 64 / 4))
|
||||
{
|
||||
*--numstr = '0';
|
||||
*--wnumstr = L_('0');
|
||||
}
|
||||
|
||||
if (sizeof (unsigned long int) > 6)
|
||||
{
|
||||
numstr = _itoa_word (num0, numstr, 16, info->spec == 'A');
|
||||
wnumstr = _itowa_word (num0, wnumstr, 16, info->spec == 'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
numstr = _itoa (num0, numstr, 16, info->spec == 'A');
|
||||
wnumstr = _itowa (num0, wnumstr, 16, info->spec == 'A');
|
||||
}
|
||||
|
||||
/* Fill with zeroes. */
|
||||
while (numstr > numbuf + (sizeof numbuf - 112 / 4))
|
||||
{
|
||||
*--numstr = '0';
|
||||
*--wnumstr = L_('0');
|
||||
}
|
||||
|
||||
leading = fpnum.ieee.exponent == 0 ? '0' : '1';
|
||||
|
||||
exponent = fpnum.ieee.exponent;
|
||||
|
||||
if (exponent == 0)
|
||||
{
|
||||
if (zero_mantissa)
|
||||
expnegative = 0;
|
||||
else
|
||||
{
|
||||
/* This is a denormalized number. */
|
||||
expnegative = 1;
|
||||
exponent = IEEE854_FLOAT128_BIAS - 1;
|
||||
}
|
||||
}
|
||||
else if (exponent >= IEEE854_FLOAT128_BIAS)
|
||||
{
|
||||
expnegative = 0;
|
||||
exponent -= IEEE854_FLOAT128_BIAS;
|
||||
}
|
||||
else
|
||||
{
|
||||
expnegative = 1;
|
||||
exponent = -(exponent - IEEE854_FLOAT128_BIAS);
|
||||
}
|
||||
}
|
||||
|
||||
/* Look for trailing zeroes. */
|
||||
if (! zero_mantissa)
|
||||
{
|
||||
wnumend = &wnumbuf[sizeof wnumbuf / sizeof wnumbuf[0]];
|
||||
numend = &numbuf[sizeof numbuf / sizeof numbuf[0]];
|
||||
while (wnumend[-1] == L_('0'))
|
||||
{
|
||||
--wnumend;
|
||||
--numend;
|
||||
}
|
||||
|
||||
if (precision == -1)
|
||||
precision = numend - numstr;
|
||||
else if (precision < numend - numstr
|
||||
&& (numstr[precision] > '8'
|
||||
|| (('A' < '0' || 'a' < '0')
|
||||
&& numstr[precision] < '0')
|
||||
|| (numstr[precision] == '8'
|
||||
&& (precision + 1 < numend - numstr
|
||||
/* Round to even. */
|
||||
|| (precision > 0
|
||||
&& ((numstr[precision - 1] & 1)
|
||||
^ (isdigit (numstr[precision - 1]) == 0)))
|
||||
|| (precision == 0
|
||||
&& ((leading & 1)
|
||||
^ (isdigit (leading) == 0)))))))
|
||||
{
|
||||
/* Round up. */
|
||||
int cnt = precision;
|
||||
while (--cnt >= 0)
|
||||
{
|
||||
char ch = numstr[cnt];
|
||||
/* We assume that the digits and the letters are ordered
|
||||
like in ASCII. This is true for the rest of GNU, too. */
|
||||
if (ch == '9')
|
||||
{
|
||||
wnumstr[cnt] = (wchar_t) info->spec;
|
||||
numstr[cnt] = info->spec; /* This is tricky,
|
||||
think about it! */
|
||||
break;
|
||||
}
|
||||
else if (tolower (ch) < 'f')
|
||||
{
|
||||
++numstr[cnt];
|
||||
++wnumstr[cnt];
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
numstr[cnt] = '0';
|
||||
wnumstr[cnt] = L_('0');
|
||||
}
|
||||
}
|
||||
if (cnt < 0)
|
||||
{
|
||||
/* The mantissa so far was fff...f Now increment the
|
||||
leading digit. Here it is again possible that we
|
||||
get an overflow. */
|
||||
if (leading == '9')
|
||||
leading = info->spec;
|
||||
else if (tolower (leading) < 'f')
|
||||
++leading;
|
||||
else
|
||||
{
|
||||
leading = '1';
|
||||
if (expnegative)
|
||||
{
|
||||
exponent -= 4;
|
||||
if (exponent <= 0)
|
||||
{
|
||||
exponent = -exponent;
|
||||
expnegative = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
exponent += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (precision == -1)
|
||||
precision = 0;
|
||||
numend = numstr;
|
||||
wnumend = wnumstr;
|
||||
}
|
||||
|
||||
/* Now we can compute the exponent string. */
|
||||
expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
|
||||
wexpstr = _itowa_word (exponent,
|
||||
wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
|
||||
|
||||
/* Now we have all information to compute the size. */
|
||||
width -= ((negative || info->showsign || info->space)
|
||||
/* Sign. */
|
||||
+ 2 + 1 + 0 + precision + 1 + 1
|
||||
/* 0x h . hhh P ExpoSign. */
|
||||
+ ((expbuf + sizeof expbuf) - expstr));
|
||||
/* Exponent. */
|
||||
|
||||
/* Count the decimal point.
|
||||
A special case when the mantissa or the precision is zero and the `#'
|
||||
is not given. In this case we must not print the decimal point. */
|
||||
if (precision > 0 || info->alt)
|
||||
width -= wide ? 1 : strlen (decimal);
|
||||
|
||||
if (!info->left && info->pad != '0' && width > 0)
|
||||
PADN (' ', width);
|
||||
|
||||
if (negative)
|
||||
outchar ('-');
|
||||
else if (info->showsign)
|
||||
outchar ('+');
|
||||
else if (info->space)
|
||||
outchar (' ');
|
||||
|
||||
outchar ('0');
|
||||
if ('X' - 'A' == 'x' - 'a')
|
||||
outchar (info->spec + ('x' - 'a'));
|
||||
else
|
||||
outchar (info->spec == 'A' ? 'X' : 'x');
|
||||
|
||||
if (!info->left && info->pad == '0' && width > 0)
|
||||
PADN ('0', width);
|
||||
|
||||
outchar (leading);
|
||||
|
||||
if (precision > 0 || info->alt)
|
||||
{
|
||||
const wchar_t *wtmp = &decimalwc;
|
||||
PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
|
||||
}
|
||||
|
||||
if (precision > 0)
|
||||
{
|
||||
ssize_t tofill = precision - (numend - numstr);
|
||||
PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
|
||||
if (tofill > 0)
|
||||
PADN ('0', tofill);
|
||||
}
|
||||
|
||||
if ('P' - 'A' == 'p' - 'a')
|
||||
outchar (info->spec + ('p' - 'a'));
|
||||
else
|
||||
outchar (info->spec == 'A' ? 'P' : 'p');
|
||||
|
||||
outchar (expnegative ? '-' : '+');
|
||||
|
||||
PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
|
||||
|
||||
if (info->left && info->pad != '0' && width > 0)
|
||||
PADN (info->pad, width);
|
||||
|
||||
return done;
|
||||
}
|
421
libquadmath/printf/quadmath-printf.c
Normal file
421
libquadmath/printf/quadmath-printf.c
Normal file
@ -0,0 +1,421 @@
|
||||
/* GCC Quad-Precision Math Library
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
This file is part of the libquadmath library.
|
||||
Libquadmath is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libquadmath is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libquadmath; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "quadmath-printf.h"
|
||||
|
||||
/* Read a simple integer from a string and update the string pointer.
|
||||
It is assumed that the first character is a digit. */
|
||||
static unsigned int
|
||||
read_int (const char **pstr)
|
||||
{
|
||||
unsigned int retval = (unsigned char) **pstr - '0';
|
||||
|
||||
while (isdigit ((unsigned char) *++(*pstr)))
|
||||
{
|
||||
retval *= 10;
|
||||
retval += (unsigned char) **pstr - '0';
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define PADSIZE 16
|
||||
static char const blanks[PADSIZE] =
|
||||
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
|
||||
static char const zeroes[PADSIZE] =
|
||||
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
|
||||
static wchar_t const wblanks[PADSIZE] =
|
||||
{
|
||||
L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '),
|
||||
L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' '), L_(' ')
|
||||
};
|
||||
static wchar_t const wzeroes[PADSIZE] =
|
||||
{
|
||||
L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'),
|
||||
L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0'), L_('0')
|
||||
};
|
||||
|
||||
attribute_hidden size_t
|
||||
__quadmath_do_pad (struct __quadmath_printf_file *fp, int wide, int c,
|
||||
size_t n)
|
||||
{
|
||||
ssize_t i;
|
||||
char padbuf[PADSIZE];
|
||||
wchar_t wpadbuf[PADSIZE];
|
||||
const char *padstr;
|
||||
size_t w, written = 0;
|
||||
if (wide)
|
||||
{
|
||||
if (c == ' ')
|
||||
padstr = (const char *) wblanks;
|
||||
else if (c == '0')
|
||||
padstr = (const char *) wzeroes;
|
||||
else
|
||||
{
|
||||
padstr = (const char *) wpadbuf;
|
||||
for (i = 0; i < PADSIZE; i++)
|
||||
wpadbuf[i] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c == ' ')
|
||||
padstr = blanks;
|
||||
else if (c == '0')
|
||||
padstr = zeroes;
|
||||
else
|
||||
{
|
||||
padstr = (const char *) padbuf;
|
||||
for (i = 0; i < PADSIZE; i++)
|
||||
padbuf[i] = c;
|
||||
}
|
||||
}
|
||||
for (i = n; i >= PADSIZE; i -= PADSIZE)
|
||||
{
|
||||
w = PUT (fp, (char *) padstr, PADSIZE);
|
||||
written += w;
|
||||
if (w != PADSIZE)
|
||||
return written;
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
w = PUT (fp, (char *) padstr, i);
|
||||
written += w;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
/* This is a stripped down version of snprintf, which just handles
|
||||
a single %eEfFgGaA format entry with Q modifier. % has to be
|
||||
the first character of the format string, no $ can be used. */
|
||||
int
|
||||
quadmath_snprintf (char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
struct printf_info info;
|
||||
va_list ap;
|
||||
__float128 fpnum, *fpnum_addr = &fpnum, **fpnum_addr2 = &fpnum_addr;
|
||||
struct __quadmath_printf_file qfp;
|
||||
|
||||
if (*format++ != '%')
|
||||
return -1;
|
||||
|
||||
/* Clear information structure. */
|
||||
info.alt = 0;
|
||||
info.space = 0;
|
||||
info.left = 0;
|
||||
info.showsign = 0;
|
||||
info.group = 0;
|
||||
info.i18n = 0;
|
||||
info.extra = 0;
|
||||
info.pad = ' ';
|
||||
info.wide = 0;
|
||||
|
||||
/* Check for spec modifiers. */
|
||||
do
|
||||
{
|
||||
switch (*format)
|
||||
{
|
||||
case ' ':
|
||||
/* Output a space in place of a sign, when there is no sign. */
|
||||
info.space = 1;
|
||||
continue;
|
||||
case '+':
|
||||
/* Always output + or - for numbers. */
|
||||
info.showsign = 1;
|
||||
continue;
|
||||
case '-':
|
||||
/* Left-justify things. */
|
||||
info.left = 1;
|
||||
continue;
|
||||
case '#':
|
||||
/* Use the "alternate form":
|
||||
Hex has 0x or 0X, FP always has a decimal point. */
|
||||
info.alt = 1;
|
||||
continue;
|
||||
case '0':
|
||||
/* Pad with 0s. */
|
||||
info.pad = '0';
|
||||
continue;
|
||||
case '\'':
|
||||
/* Show grouping in numbers if the locale information
|
||||
indicates any. */
|
||||
info.group = 1;
|
||||
continue;
|
||||
case 'I':
|
||||
/* Use the internationalized form of the output. Currently
|
||||
means to use the `outdigits' of the current locale. */
|
||||
info.i18n = 1;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
while (*++format);
|
||||
|
||||
if (info.left)
|
||||
info.pad = ' ';
|
||||
|
||||
va_start (ap, format);
|
||||
|
||||
/* Get the field width. */
|
||||
info.width = 0;
|
||||
if (*format == '*')
|
||||
{
|
||||
/* The field width is given in an argument.
|
||||
A negative field width indicates left justification. */
|
||||
++format;
|
||||
info.width = va_arg (ap, int);
|
||||
}
|
||||
else if (isdigit (*format))
|
||||
/* Constant width specification. */
|
||||
info.width = read_int (&format);
|
||||
|
||||
/* Get the precision. */
|
||||
/* -1 means none given; 0 means explicit 0. */
|
||||
info.prec = -1;
|
||||
if (*format == '.')
|
||||
{
|
||||
++format;
|
||||
if (*format == '*')
|
||||
{
|
||||
/* The precision is given in an argument. */
|
||||
++format;
|
||||
|
||||
info.prec = va_arg (ap, int);
|
||||
}
|
||||
else if (isdigit (*format))
|
||||
info.prec = read_int (&format);
|
||||
else
|
||||
/* "%.?" is treated like "%.0?". */
|
||||
info.prec = 0;
|
||||
}
|
||||
|
||||
/* Check for type modifiers. */
|
||||
info.is_long_double = 0;
|
||||
info.is_short = 0;
|
||||
info.is_long = 0;
|
||||
info.is_char = 0;
|
||||
info.user = -1;
|
||||
|
||||
/* We require Q modifier. */
|
||||
if (*format++ != 'Q')
|
||||
{
|
||||
va_end (ap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the format specification. */
|
||||
info.spec = (wchar_t) *format++;
|
||||
if (info.spec == L_('\0') || *format != '\0')
|
||||
{
|
||||
va_end (ap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (info.spec)
|
||||
{
|
||||
case L_('e'):
|
||||
case L_('E'):
|
||||
case L_('f'):
|
||||
case L_('F'):
|
||||
case L_('g'):
|
||||
case L_('G'):
|
||||
case L_('a'):
|
||||
case L_('A'):
|
||||
break;
|
||||
default:
|
||||
va_end (ap);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fpnum = va_arg (ap, __float128);
|
||||
va_end (ap);
|
||||
|
||||
qfp.fp = NULL;
|
||||
qfp.str = str;
|
||||
qfp.size = size;
|
||||
qfp.len = 0;
|
||||
qfp.file_p = 0;
|
||||
|
||||
if (info.spec == L_('a') || info.spec == L_('A'))
|
||||
__quadmath_printf_fphex (&qfp, &info, (const void *const *)&fpnum_addr2);
|
||||
else
|
||||
__quadmath_printf_fp (&qfp, &info, (const void *const *)&fpnum_addr2);
|
||||
|
||||
if (qfp.size)
|
||||
*qfp.str = '\0';
|
||||
|
||||
return qfp.len;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRINTF_HOOKS
|
||||
static int pa_flt128;
|
||||
int mod_Q attribute_hidden;
|
||||
|
||||
static void
|
||||
flt128_va (void *mem, va_list *ap)
|
||||
{
|
||||
__float128 d = va_arg (*ap, __float128);
|
||||
memcpy (mem, &d, sizeof (d));
|
||||
}
|
||||
|
||||
static int
|
||||
flt128_ais (const struct printf_info *info, size_t n __attribute__ ((unused)),
|
||||
int *argtype, int *size)
|
||||
{
|
||||
if (info->user & mod_Q)
|
||||
{
|
||||
argtype[0] = pa_flt128;
|
||||
size[0] = sizeof (__float128);
|
||||
return 1;
|
||||
}
|
||||
#if __GLIBC_MINOR__ <= 13
|
||||
/* Workaround bug in glibc printf hook handling. */
|
||||
size[0] = -1;
|
||||
switch (info->spec)
|
||||
{
|
||||
case L_('i'):
|
||||
case L_('d'):
|
||||
case L_('u'):
|
||||
case L_('o'):
|
||||
case L_('X'):
|
||||
case L_('x'):
|
||||
#if __LONG_MAX__ != __LONG_LONG_MAX__
|
||||
if (info->is_long_double)
|
||||
argtype[0] = PA_INT|PA_FLAG_LONG_LONG;
|
||||
else
|
||||
#endif
|
||||
if (info->is_long)
|
||||
argtype[0] = PA_INT|PA_FLAG_LONG;
|
||||
else if (info->is_short)
|
||||
argtype[0] = PA_INT|PA_FLAG_SHORT;
|
||||
else if (info->is_char)
|
||||
argtype[0] = PA_CHAR;
|
||||
else
|
||||
argtype[0] = PA_INT;
|
||||
return 1;
|
||||
case L_('e'):
|
||||
case L_('E'):
|
||||
case L_('f'):
|
||||
case L_('F'):
|
||||
case L_('g'):
|
||||
case L_('G'):
|
||||
case L_('a'):
|
||||
case L_('A'):
|
||||
if (info->is_long_double)
|
||||
argtype[0] = PA_DOUBLE|PA_FLAG_LONG_DOUBLE;
|
||||
else
|
||||
argtype[0] = PA_DOUBLE;
|
||||
return 1;
|
||||
case L_('c'):
|
||||
argtype[0] = PA_CHAR;
|
||||
return 1;
|
||||
case L_('C'):
|
||||
argtype[0] = PA_WCHAR;
|
||||
return 1;
|
||||
case L_('s'):
|
||||
argtype[0] = PA_STRING;
|
||||
return 1;
|
||||
case L_('S'):
|
||||
argtype[0] = PA_WSTRING;
|
||||
return 1;
|
||||
case L_('p'):
|
||||
argtype[0] = PA_POINTER;
|
||||
return 1;
|
||||
case L_('n'):
|
||||
argtype[0] = PA_INT|PA_FLAG_PTR;
|
||||
return 1;
|
||||
|
||||
case L_('m'):
|
||||
default:
|
||||
/* An unknown spec will consume no args. */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
flt128_printf_fp (FILE *fp, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
struct __quadmath_printf_file qpf
|
||||
= { .fp = fp, .str = NULL, .size = 0, .len = 0, .file_p = 1 };
|
||||
|
||||
if ((info->user & mod_Q) == 0)
|
||||
return -2;
|
||||
|
||||
return __quadmath_printf_fp (&qpf, info, args);
|
||||
}
|
||||
|
||||
static int
|
||||
flt128_printf_fphex (FILE *fp, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
struct __quadmath_printf_file qpf
|
||||
= { .fp = fp, .str = NULL, .size = 0, .len = 0, .file_p = 1 };
|
||||
|
||||
if ((info->user & mod_Q) == 0)
|
||||
return -2;
|
||||
|
||||
return __quadmath_printf_fphex (&qpf, info, args);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) static void
|
||||
register_printf_flt128 (void)
|
||||
{
|
||||
pa_flt128 = register_printf_type (flt128_va);
|
||||
if (pa_flt128 == -1)
|
||||
return;
|
||||
mod_Q = register_printf_modifier (L_("Q"));
|
||||
if (mod_Q == -1)
|
||||
return;
|
||||
register_printf_specifier ('f', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('F', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('e', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('E', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('g', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('G', flt128_printf_fp, flt128_ais);
|
||||
register_printf_specifier ('a', flt128_printf_fphex, flt128_ais);
|
||||
register_printf_specifier ('A', flt128_printf_fphex, flt128_ais);
|
||||
}
|
||||
|
||||
__attribute__((destructor)) static void
|
||||
unregister_printf_flt128 (void)
|
||||
{
|
||||
/* No way to unregister printf type and modifier currently,
|
||||
and only one printf specifier can be registered right now. */
|
||||
if (pa_flt128 == -1 || mod_Q == -1)
|
||||
return;
|
||||
register_printf_specifier ('f', NULL, NULL);
|
||||
register_printf_specifier ('F', NULL, NULL);
|
||||
register_printf_specifier ('e', NULL, NULL);
|
||||
register_printf_specifier ('E', NULL, NULL);
|
||||
register_printf_specifier ('g', NULL, NULL);
|
||||
register_printf_specifier ('G', NULL, NULL);
|
||||
register_printf_specifier ('a', NULL, NULL);
|
||||
register_printf_specifier ('A', NULL, NULL);
|
||||
}
|
||||
#endif
|
167
libquadmath/printf/quadmath-printf.h
Normal file
167
libquadmath/printf/quadmath-printf.h
Normal file
@ -0,0 +1,167 @@
|
||||
/* GCC Quad-Precision Math Library
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
Written by Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
This file is part of the libquadmath library.
|
||||
Libquadmath is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libquadmath is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libquadmath; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifdef HAVE_LANGINFO_H
|
||||
#include <langinfo.h>
|
||||
#endif
|
||||
#ifdef HAVE_CTYPE_H
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
#ifdef HAVE_WCHAR_H
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
#ifdef HAVE_WCTYPE_H
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
#ifdef HAVE_PRINTF_HOOKS
|
||||
#include <printf.h>
|
||||
#endif
|
||||
#include "quadmath-imp.h"
|
||||
#include "gmp-impl.h"
|
||||
|
||||
#ifdef HAVE_WCHAR_H
|
||||
#define L_(x) L##x
|
||||
#else
|
||||
#define L_(x) x
|
||||
#undef wchar_t
|
||||
#undef wint_t
|
||||
#undef putwc
|
||||
#undef WEOF
|
||||
#define wchar_t char
|
||||
#define wint_t int
|
||||
#define putwc(c,f) putc(c,f)
|
||||
#define WEOF EOF
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CTYPE_H
|
||||
/* Won't work for EBCDIC. */
|
||||
#undef isupper
|
||||
#undef isdigit
|
||||
#undef tolower
|
||||
#define isupper(x) ((x) >= 'A' && (x) <= 'Z')
|
||||
#define isdigit(x) ((x) >= '0' && (x) <= '9')
|
||||
#define tolower(x) (isupper (x) ? (x) - 'A' + 'a' : (x))
|
||||
#endif
|
||||
|
||||
#ifndef CHAR_MAX
|
||||
#ifdef __CHAR_UNSIGNED__
|
||||
#define CHAR_MAX (2 * __SCHAR_MAX__ + 1)
|
||||
#else
|
||||
#define CHAR_MAX __SCHAR_MAX__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PRINTF_HOOKS
|
||||
#define printf_info __quadmath_printf_info
|
||||
struct printf_info
|
||||
{
|
||||
int prec; /* Precision. */
|
||||
int width; /* Width. */
|
||||
wchar_t spec; /* Format letter. */
|
||||
unsigned int is_long_double:1;/* L flag. */
|
||||
unsigned int is_short:1; /* h flag. */
|
||||
unsigned int is_long:1; /* l flag. */
|
||||
unsigned int alt:1; /* # flag. */
|
||||
unsigned int space:1; /* Space flag. */
|
||||
unsigned int left:1; /* - flag. */
|
||||
unsigned int showsign:1; /* + flag. */
|
||||
unsigned int group:1; /* ' flag. */
|
||||
unsigned int extra:1; /* For special use. */
|
||||
unsigned int is_char:1; /* hh flag. */
|
||||
unsigned int wide:1; /* Nonzero for wide character streams. */
|
||||
unsigned int i18n:1; /* I flag. */
|
||||
unsigned short int user; /* Bits for user-installed modifiers. */
|
||||
wchar_t pad; /* Padding character. */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct __quadmath_printf_file
|
||||
{
|
||||
FILE *fp;
|
||||
char *str;
|
||||
size_t size;
|
||||
size_t len;
|
||||
int file_p;
|
||||
};
|
||||
|
||||
int
|
||||
__quadmath_printf_fp (struct __quadmath_printf_file *fp,
|
||||
const struct printf_info *info,
|
||||
const void *const *args) attribute_hidden;
|
||||
int
|
||||
__quadmath_printf_fphex (struct __quadmath_printf_file *fp,
|
||||
const struct printf_info *info,
|
||||
const void *const *args) attribute_hidden;
|
||||
|
||||
size_t __quadmath_do_pad (struct __quadmath_printf_file *fp, int wide,
|
||||
int c, size_t n) attribute_hidden;
|
||||
|
||||
static inline __attribute__((__unused__)) size_t
|
||||
__quadmath_do_put (struct __quadmath_printf_file *fp, int wide,
|
||||
const char *s, size_t n)
|
||||
{
|
||||
size_t len;
|
||||
if (fp->file_p)
|
||||
{
|
||||
if (wide)
|
||||
{
|
||||
size_t cnt;
|
||||
const wchar_t *ls = (const wchar_t *) s;
|
||||
for (cnt = 0; cnt < n; cnt++)
|
||||
if (putwc (ls[cnt], fp->fp) == WEOF)
|
||||
break;
|
||||
return cnt;
|
||||
}
|
||||
return fwrite (s, 1, n, fp->fp);
|
||||
}
|
||||
len = MIN (fp->size, n);
|
||||
memcpy (fp->str, s, len);
|
||||
fp->str += len;
|
||||
fp->size -= len;
|
||||
fp->len += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline __attribute__((__unused__)) int
|
||||
__quadmath_do_putc (struct __quadmath_printf_file *fp, int wide,
|
||||
wchar_t c)
|
||||
{
|
||||
if (fp->file_p)
|
||||
return wide ? (int) putwc (c, fp->fp) : putc (c, fp->fp);
|
||||
if (fp->size)
|
||||
{
|
||||
*(fp->str++) = c;
|
||||
fp->size--;
|
||||
}
|
||||
fp->len++;
|
||||
return (unsigned char) c;
|
||||
}
|
||||
|
||||
#define PUT(f, s, n) __quadmath_do_put (f, wide, s, n)
|
||||
#define PAD(f, c, n) __quadmath_do_pad (f, wide, c, n)
|
||||
#define PUTC(c, f) __quadmath_do_putc (f, wide, c)
|
||||
|
||||
#define nl_langinfo_wc(x) \
|
||||
({ union { const char *mb; wchar_t wc; } u; u.mb = nl_langinfo (x); u.wc; })
|
87
libquadmath/printf/rshift.c
Normal file
87
libquadmath/printf/rshift.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* mpn_rshift -- Shift right a low-level natural-number integer.
|
||||
|
||||
Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
|
||||
and store the USIZE least significant limbs of the result at WP.
|
||||
The bits shifted out to the right are returned.
|
||||
|
||||
Argument constraints:
|
||||
1. 0 < CNT < BITS_PER_MP_LIMB
|
||||
2. If the result is to be written over the input, WP must be <= UP.
|
||||
*/
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_rshift (register mp_ptr wp,
|
||||
register mp_srcptr up, mp_size_t usize,
|
||||
register unsigned int cnt)
|
||||
#else
|
||||
mpn_rshift (wp, up, usize, cnt)
|
||||
register mp_ptr wp;
|
||||
register mp_srcptr up;
|
||||
mp_size_t usize;
|
||||
register unsigned int cnt;
|
||||
#endif
|
||||
{
|
||||
register mp_limb_t high_limb, low_limb;
|
||||
register unsigned sh_1, sh_2;
|
||||
register mp_size_t i;
|
||||
mp_limb_t retval;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (usize == 0 || cnt == 0)
|
||||
abort ();
|
||||
#endif
|
||||
|
||||
sh_1 = cnt;
|
||||
|
||||
#if 0
|
||||
if (sh_1 == 0)
|
||||
{
|
||||
if (wp != up)
|
||||
{
|
||||
/* Copy from low end to high end, to allow specified input/output
|
||||
overlapping. */
|
||||
for (i = 0; i < usize; i++)
|
||||
wp[i] = up[i];
|
||||
}
|
||||
return usize;
|
||||
}
|
||||
#endif
|
||||
|
||||
wp -= 1;
|
||||
sh_2 = BITS_PER_MP_LIMB - sh_1;
|
||||
high_limb = up[0];
|
||||
retval = high_limb << sh_2;
|
||||
low_limb = high_limb;
|
||||
|
||||
for (i = 1; i < usize; i++)
|
||||
{
|
||||
high_limb = up[i];
|
||||
wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
|
||||
low_limb = high_limb;
|
||||
}
|
||||
wp[i] = low_limb >> sh_1;
|
||||
|
||||
return retval;
|
||||
}
|
61
libquadmath/printf/sub_n.c
Normal file
61
libquadmath/printf/sub_n.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* mpn_sub_n -- Subtract two limb vectors of equal, non-zero length.
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
mp_limb_t
|
||||
#if __STDC__
|
||||
mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr, mp_size_t size)
|
||||
#else
|
||||
mpn_sub_n (res_ptr, s1_ptr, s2_ptr, size)
|
||||
register mp_ptr res_ptr;
|
||||
register mp_srcptr s1_ptr;
|
||||
register mp_srcptr s2_ptr;
|
||||
mp_size_t size;
|
||||
#endif
|
||||
{
|
||||
register mp_limb_t x, y, cy;
|
||||
register mp_size_t j;
|
||||
|
||||
/* The loop counter and index J goes from -SIZE to -1. This way
|
||||
the loop becomes faster. */
|
||||
j = -size;
|
||||
|
||||
/* Offset the base pointers to compensate for the negative indices. */
|
||||
s1_ptr -= j;
|
||||
s2_ptr -= j;
|
||||
res_ptr -= j;
|
||||
|
||||
cy = 0;
|
||||
do
|
||||
{
|
||||
y = s2_ptr[j];
|
||||
x = s1_ptr[j];
|
||||
y += cy; /* add previous carry to subtrahend */
|
||||
cy = (y < cy); /* get out carry from that addition */
|
||||
y = x - y; /* main subtract */
|
||||
cy = (y > x) + cy; /* get out carry from the subtract, combine */
|
||||
res_ptr[j] = y;
|
||||
}
|
||||
while (++j != 0);
|
||||
|
||||
return cy;
|
||||
}
|
63
libquadmath/printf/submul_1.c
Normal file
63
libquadmath/printf/submul_1.c
Normal file
@ -0,0 +1,63 @@
|
||||
/* mpn_submul_1 -- multiply the S1_SIZE long limb vector pointed to by S1_PTR
|
||||
by S2_LIMB, subtract the S1_SIZE least significant limbs of the product
|
||||
from the limb vector pointed to by RES_PTR. Return the most significant
|
||||
limb of the product, adjusted for carry-out from the subtraction.
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1996, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
The GNU MP Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA. */
|
||||
|
||||
#include "gmp-impl.h"
|
||||
|
||||
mp_limb_t
|
||||
mpn_submul_1 (res_ptr, s1_ptr, s1_size, s2_limb)
|
||||
register mp_ptr res_ptr;
|
||||
register mp_srcptr s1_ptr;
|
||||
mp_size_t s1_size;
|
||||
register mp_limb_t s2_limb;
|
||||
{
|
||||
register mp_limb_t cy_limb;
|
||||
register mp_size_t j;
|
||||
register mp_limb_t prod_high, prod_low;
|
||||
register mp_limb_t x;
|
||||
|
||||
/* The loop counter and index J goes from -SIZE to -1. This way
|
||||
the loop becomes faster. */
|
||||
j = -s1_size;
|
||||
|
||||
/* Offset the base pointers to compensate for the negative indices. */
|
||||
res_ptr -= j;
|
||||
s1_ptr -= j;
|
||||
|
||||
cy_limb = 0;
|
||||
do
|
||||
{
|
||||
umul_ppmm (prod_high, prod_low, s1_ptr[j], s2_limb);
|
||||
|
||||
prod_low += cy_limb;
|
||||
cy_limb = (prod_low < cy_limb) + prod_high;
|
||||
|
||||
x = res_ptr[j];
|
||||
prod_low = x - prod_low;
|
||||
cy_limb += (prod_low > x);
|
||||
res_ptr[j] = prod_low;
|
||||
}
|
||||
while (++j != 0);
|
||||
|
||||
return cy_limb;
|
||||
}
|
@ -132,8 +132,8 @@ extern __complex128 ctanhq (__complex128) __quadmath_throw;
|
||||
|
||||
/* Prototypes for string <-> __float128 conversion functions */
|
||||
extern __float128 strtoflt128 (const char *, char **) __quadmath_throw;
|
||||
extern void quadmath_flt128tostr (char *, size_t, size_t, __float128)
|
||||
__quadmath_throw;
|
||||
extern int quadmath_snprintf (char *str, size_t size,
|
||||
const char *format, ...) __quadmath_throw;
|
||||
|
||||
|
||||
/* Macros */
|
||||
|
@ -92,7 +92,7 @@ QUADMATH_1.0 {
|
||||
ctanhq;
|
||||
|
||||
strtoflt128;
|
||||
quadmath_flt128tostr;
|
||||
quadmath_snprintf;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
@ -1,110 +0,0 @@
|
||||
/* GCC Quad-Precision Math Library
|
||||
Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
|
||||
This file is part of the libquadmath library.
|
||||
Libquadmath is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
Libquadmath is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with libquadmath; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
#include "quadmath.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ABS(x) ((x) >= 0 ? (x) : -(x))
|
||||
|
||||
|
||||
|
||||
static void
|
||||
format (char * res, const __float128 x, size_t n)
|
||||
{
|
||||
char buffer[1024];
|
||||
char *p;
|
||||
|
||||
memset (buffer, 0, sizeof(buffer));
|
||||
|
||||
g_Qfmt (buffer, &x, n + 1, sizeof(buffer) - 3);
|
||||
p = buffer + (*buffer == '-' ? 1 : 0);
|
||||
|
||||
/* The sign is the easiest part. */
|
||||
res[0] = (signbitq (x) ? '-' : '+');
|
||||
|
||||
if (*p == '.')
|
||||
{
|
||||
/* We have a number smaller than 1, without exponent. */
|
||||
int exp = 0;
|
||||
char *c;
|
||||
|
||||
for (c = p+1; *c == '0'; c++)
|
||||
exp++;
|
||||
|
||||
/* We move the string "exp" characters left. */
|
||||
size_t l = strlen (p+1+exp);
|
||||
memcpy (res + 2, p + 1 + exp, l);
|
||||
memset (res + 2 + l, '0', n - l + 1);
|
||||
sprintf (res + n + 3, "e-%02d", exp + 1);
|
||||
|
||||
res[1] = res[2];
|
||||
res[2] = '.';
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, do we already have an exponent. */
|
||||
char *c;
|
||||
for (c = p; *c && *c != 'e'; c++)
|
||||
;
|
||||
if (*c)
|
||||
{
|
||||
int exp = strtol (c + 1, NULL, 10);
|
||||
|
||||
size_t l = c - p;
|
||||
|
||||
memcpy (res + 1, p, l);
|
||||
if (l <= n + 1)
|
||||
memset (res + 1 + l, '0', (int) n - l + 2);
|
||||
|
||||
sprintf (res + n + 3, "e%c%02d", exp >= 0 ? '+' : '-', ABS(exp));
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we have no exponent, normalize and add the exponent. */
|
||||
for (c = p; *c && *c != '.'; c++)
|
||||
;
|
||||
|
||||
res[1] = *p;
|
||||
res[2] = '.';
|
||||
|
||||
size_t l = c - p;
|
||||
memcpy (res + 3, p + 1, l);
|
||||
size_t l2 = strlen (c + 1);
|
||||
memcpy (res + 2 + l, c + 1, l2);
|
||||
memset (res + 2 + l + l2, '0', n - (l + l2) + 1);
|
||||
sprintf (res + n + 3, "e+%02d", l - 1);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
quadmath_flt128tostr (char *s, size_t size, size_t n, __float128 x)
|
||||
{
|
||||
char buffer[1024];
|
||||
memset (buffer, 0, sizeof(buffer));
|
||||
format (buffer, x, n);
|
||||
memcpy (s, buffer, size);
|
||||
}
|
@ -132,6 +132,6 @@ __qmath3 (ctanhq)
|
||||
|
||||
/* Prototypes for string <-> flt128 conversion functions. */
|
||||
__qmath3 (strtoflt128)
|
||||
__qmath3 (quadmath_flt128tostr)
|
||||
__qmath3 (quadmath_snprintf)
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user