diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2008-09-07 20:36:11 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2008-09-07 20:36:11 +0000 |
commit | 319618ea76ca9de5c1e1b02bff3bddbdf5c46dc7 (patch) | |
tree | 402fb699f6a3a45a23dce26a3952cfee3d992421 | |
parent | 6e9298963b5a9bb500e3f8308cd681b32638fb31 (diff) |
- replace dtoa w/ David's gdtoa, version 2008-03-15
- provide proper dtoa locks
- use the real strtof implementation
- add strtold, __hdtoa, __hldtoa
- add %a/%A support
- don't lose precision in printf, don't round to double anymore
- implement extended-precision versions of libc functions: fpclassify,
isnan, isinf, signbit, isnormal, isfinite, now that the ieee.h is
fixed
- separate vax versions of strtof, and __hdtoa
- add complex math support. added functions: cacos, casin, catan,
ccos, csin, ctan, cacosh, casinh, catanh, ccosh, csinh, ctanh, cexp,
clog, cabs, cpow, csqrt, carg, cimag, conj, cproj, creal, cacosf,
casinf, catanf, ccosf, csinf, ctanf, cacoshf, casinhf, catanhf,
ccoshf, csinhf, ctanhf, cexpf, clogf, cabsf, cpowf, csqrtf, cargf,
cimagf, conjf, cprojf, crealf
- add fdim, fmax, fmin
- add log2. (adapted implementation e_log.c. could be more acruate
& faster, but it's good enough for now)
- remove wrappers & cruft in libm, supposed to work-around mistakes
in SVID, etc.; use ieee versions. fixes issues in python 2.6 for
djm@
- make _digittoint static
- proper definitions for i386, and amd64 in ieee.h
- sh, powerpc don't really have extended-precision
- add missing definitions for mips64 (quad), m{6,8}k (96-bit) float.h
for LDBL_*
- merge lead to frac for m{6,8}k, for gdtoa to work properly
- add FRAC*BITS & EXT_TO_ARRAY32 definitions in ieee.h, for hdtoa&ldtoa
to use
- add EXT_IMPLICIT_NBIT definition, which indicates implicit
normalization bit
- add regression tests for libc: fpclassify and printf
- arith.h & gd_qnan.h definitions
- update ieee.h: hppa doesn't have quad-precision, hppa64 does
- add missing prototypes to gdtoaimp
- on 64-bit platforms make sure gdtoa doesn't use a long when it
really wants an int
- etc., what i may have forgotten...
- bump libm major, due to removed&changed symbols
- no libc bump, since this is riding on djm's libc major crank from
a day ago
discussed with / requested by / testing theo, sthen@, djm@, jsg@,
merdely@, jsing@, tedu@, brad@, jakemsr@, and others.
looks good to millert@
parts of the diff ok kettenis@
this commit does not include:
- man page changes
381 files changed, 16633 insertions, 6239 deletions
diff --git a/include/Makefile b/include/Makefile index d4ff6feb66b..13ea9e5629e 100644 --- a/include/Makefile +++ b/include/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.145 2008/08/22 13:02:53 kettenis Exp $ +# $OpenBSD: Makefile,v 1.146 2008/09/07 20:36:07 martynas Exp $ # $NetBSD: Makefile,v 1.59 1996/05/15 21:36:43 jtc Exp $ # @(#)Makefile 5.45.1.1 (Berkeley) 5/6/91 @@ -12,7 +12,7 @@ USE_GCC3?=No # Missing: mp.h FILES= a.out.h ar.h assert.h bitstring.h blf.h bm.h bsd_auth.h cast.h \ - cpio.h ctype.h curses.h db.h dbm.h des.h dirent.h disktab.h \ + complex.h cpio.h ctype.h curses.h db.h dbm.h des.h dirent.h disktab.h \ dlfcn.h elf_abi.h err.h errno.h fnmatch.h fstab.h fts.h ftw.h getopt.h \ glob.h grp.h ifaddrs.h inttypes.h iso646.h kvm.h langinfo.h \ libgen.h limits.h locale.h login_cap.h malloc.h math.h md4.h \ diff --git a/include/complex.h b/include/complex.h new file mode 100644 index 00000000000..36cc3f9994b --- /dev/null +++ b/include/complex.h @@ -0,0 +1,122 @@ +/* $OpenBSD: complex.h,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +#ifndef _COMPLEX_H_ +#define _COMPLEX_H_ + +#include <sys/cdefs.h> + +/* + * C99 + */ +#ifdef __GNUC__ +#if __STDC_VERSION__ < 199901 +#define _Complex __complex__ +#endif +#define _Complex_I 1.0fi +#endif + +#define complex _Complex + +/* XXX switch to _Imaginary_I */ +#undef I +#define I _Complex_I + +__BEGIN_DECLS +/* + * Double versions of C99 functions + */ +double complex cacos(double complex); +double complex casin(double complex); +double complex catan(double complex); +double complex ccos(double complex); +double complex csin(double complex); +double complex ctan(double complex); +double complex cacosh(double complex); +double complex casinh(double complex); +double complex catanh(double complex); +double complex ccosh(double complex); +double complex csinh(double complex); +double complex ctanh(double complex); +double complex cexp(double complex); +double complex clog(double complex); +double cabs(double complex); +double complex cpow(double complex, double complex); +double complex csqrt(double complex); +double carg(double complex); +double cimag(double complex); +double complex conj(double complex); +double complex cproj(double complex); +double creal(double complex); + +/* + * Float versions of C99 functions + */ +float complex cacosf(float complex); +float complex casinf(float complex); +float complex catanf(float complex); +float complex ccosf(float complex); +float complex csinf(float complex); +float complex ctanf(float complex); +float complex cacoshf(float complex); +float complex casinhf(float complex); +float complex catanhf(float complex); +float complex ccoshf(float complex); +float complex csinhf(float complex); +float complex ctanhf(float complex); +float complex cexpf(float complex); +float complex clogf(float complex); +float cabsf(float complex); +float complex cpowf(float complex, float complex); +float complex csqrtf(float complex); +float cargf(float complex); +float cimagf(float complex); +float complex conjf(float complex); +float complex cprojf(float complex); +float crealf(float complex); + +/* + * Long double versions of C99 functions + */ +#if 0 +long double complex cacosl(long double complex); +long double complex casinl(long double complex); +long double complex catanl(long double complex); +long double complex ccosl(long double complex); +long double complex csinl(long double complex); +long double complex ctanl(long double complex); +long double complex cacoshl(long double complex); +long double complex casinhl(long double complex); +long double complex catanhl(long double complex); +long double complex ccoshl(long double complex); +long double complex csinhl(long double complex); +long double complex ctanhl(long double complex); +long double complex cexpl(long double complex); +long double complex clogl(long double complex); +long double cabsl(long double complex); +long double complex cpowl(long double complex, + long double complex); +long double complex csqrtl(long double complex); +long double cargl(long double complex); +long double cimagl(long double complex); +long double complex conjl(long double complex); +long double complex cprojl(long double complex); +long double creall(long double complex); +#endif +__END_DECLS + +#endif _COMPLEX_H_ /* !_COMPLEX_H_ */ diff --git a/include/math.h b/include/math.h index ba64e75117c..bb953739684 100644 --- a/include/math.h +++ b/include/math.h @@ -1,4 +1,4 @@ -/* $OpenBSD: math.h,v 1.20 2008/07/24 09:41:58 martynas Exp $ */ +/* $OpenBSD: math.h,v 1.21 2008/09/07 20:36:07 martynas Exp $ */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -63,18 +63,6 @@ extern char __nan[]; : (sizeof (x) == sizeof (double)) ? \ __isfinite(x) \ : __isfinitel(x)) -#define isinf(x) \ - ((sizeof (x) == sizeof (float)) ? \ - isinff(x) \ - : (sizeof (x) == sizeof (double)) ? \ - __isinf(x) \ - : __isinfl(x)) -#define isnan(x) \ - ((sizeof (x) == sizeof (float)) ? \ - isnanf(x) \ - : (sizeof (x) == sizeof (double)) ? \ - __isnan(x) \ - : __isnanl(x)) #define isnormal(x) \ ((sizeof (x) == sizeof (float)) ? \ __isnormalf(x) \ @@ -97,6 +85,19 @@ extern char __nan[]; #define isunordered(x, y) (isnan(x) || isnan(y)) #endif /* __ISO_C_VISIBLE >= 1999 */ +#define isinf(x) \ + ((sizeof (x) == sizeof (float)) ? \ + isinff(x) \ + : (sizeof (x) == sizeof (double)) ? \ + __isinf(x) \ + : __isinfl(x)) +#define isnan(x) \ + ((sizeof (x) == sizeof (float)) ? \ + isnanf(x) \ + : (sizeof (x) == sizeof (double)) ? \ + __isnan(x) \ + : __isnanl(x)) + /* * XOPEN/SVID */ @@ -125,51 +126,7 @@ extern int signgam; #endif /* __BSD_VISIBLE || __XPG_VISIBLE */ #if __BSD_VISIBLE -enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; - -#define _LIB_VERSION_TYPE enum fdversion -#define _LIB_VERSION _fdlib_version - -/* if global variable _LIB_VERSION is not desirable, one may - * change the following to be a constant by: - * #define _LIB_VERSION_TYPE const enum version - * In that case, after one initializes the value _LIB_VERSION (see - * s_lib_version.c) during compile time, it cannot be modified - * in the middle of a program - */ -extern _LIB_VERSION_TYPE _LIB_VERSION; - -#define _IEEE_ fdlibm_ieee -#define _SVID_ fdlibm_svid -#define _XOPEN_ fdlibm_xopen -#define _POSIX_ fdlibm_posix - -#ifndef __cplusplus -struct exception { - int type; - char *name; - double arg1; - double arg2; - double retval; -}; -#endif /* !__cplusplus */ - #define HUGE MAXFLOAT - -/* - * set X_TLOSS = pi*2**52, which is possibly defined in <values.h> - * (one may replace the following line by "#include <values.h>") - */ - -#define X_TLOSS 1.41484755040568800000e+16 - -#define DOMAIN 1 -#define SING 2 -#define OVERFLOW 3 -#define UNDERFLOW 4 -#define TLOSS 5 -#define PLOSS 6 - #endif /* __BSD_VISIBLE */ __BEGIN_DECLS @@ -215,9 +172,7 @@ extern double exp2(double); extern double expm1(double); extern int ilogb(double); extern double log1p(double); -#if 0 extern double log2(double); -#endif extern double logb(double); extern double scalbn(double, int); #if 0 @@ -253,11 +208,9 @@ extern double nextafter(double, double); extern double nexttoward(double, long double); #endif -#if 0 extern double fdim(double, double); extern double fmax(double, double); extern double fmin(double, double); -#endif #if 0 extern double fma(double, double, double); @@ -292,10 +245,6 @@ extern int finite(double); extern double gamma_r(double, int *); extern double lgamma_r(double, int *); -#ifdef __LIBM_PRIVATE -extern int matherr(struct exception *); -#endif /* __LIBM_PRIVATE */ - /* * IEEE Test Vector */ @@ -375,11 +324,9 @@ extern float nextafterf(float, float); extern float nexttowardf(float, long double); #endif -#if 0 extern float fdimf(float, float); extern float fmaxf(float, float); extern float fminf(float, float); -#endif #if 0 extern float fmaf(float, float, float); diff --git a/include/stdlib.h b/include/stdlib.h index bd1a28386b8..496090a50db 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: stdlib.h,v 1.44 2008/06/24 06:01:33 otto Exp $ */ +/* $OpenBSD: stdlib.h,v 1.45 2008/09/07 20:36:07 martynas Exp $ */ /* $NetBSD: stdlib.h,v 1.25 1995/12/27 21:19:08 jtc Exp $ */ /*- @@ -132,6 +132,8 @@ void srand(unsigned); double strtod(const char *, char **); float strtof(const char *, char **); long strtol(const char *, char **, int); +long double + strtold(const char *, char **); unsigned long strtoul(const char *, char **, int); int system(const char *); diff --git a/lib/libc/Makefile.inc b/lib/libc/Makefile.inc index 2530ec86a47..cd3e853efd5 100644 --- a/lib/libc/Makefile.inc +++ b/lib/libc/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.11 2005/06/17 20:37:31 drahn Exp $ +# $OpenBSD: Makefile.inc,v 1.12 2008/09/07 20:36:07 martynas Exp $ # # This file contains make rules used to build libc # @@ -33,6 +33,7 @@ AINC+= -nostdinc -idirafter ${DESTDIR}/usr/include .include "${LIBCSRCDIR}/compat-43/Makefile.inc" .include "${LIBCSRCDIR}/gen/Makefile.inc" .include "${LIBCSRCDIR}/crypt/Makefile.inc" +.include "${LIBCSRCDIR}/gdtoa/Makefile.inc" .include "${LIBCSRCDIR}/gmon/Makefile.inc" .include "${LIBCSRCDIR}/hash/Makefile.inc" .include "${LIBCSRCDIR}/locale/Makefile.inc" diff --git a/lib/libc/arch/alpha/gdtoa/Makefile.inc b/lib/libc/arch/alpha/gdtoa/Makefile.inc new file mode 100644 index 00000000000..b74c512bc69 --- /dev/null +++ b/lib/libc/arch/alpha/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c diff --git a/lib/libc/arch/alpha/gdtoa/arith.h b/lib/libc/arch/alpha/gdtoa/arith.h new file mode 100644 index 00000000000..32513b96e90 --- /dev/null +++ b/lib/libc/arch/alpha/gdtoa/arith.h @@ -0,0 +1,6 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/arch/alpha/gdtoa/gd_qnan.h b/lib/libc/arch/alpha/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..99313b9adca --- /dev/null +++ b/lib/libc/arch/alpha/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0xffc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0xfff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xfff80000 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xfff8 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/amd64/gdtoa/Makefile.inc b/lib/libc/arch/amd64/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9b47fc51d00 --- /dev/null +++ b/lib/libc/arch/amd64/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorx.c diff --git a/lib/libc/arch/amd64/gdtoa/arith.h b/lib/libc/arch/amd64/gdtoa/arith.h new file mode 100644 index 00000000000..32513b96e90 --- /dev/null +++ b/lib/libc/arch/amd64/gdtoa/arith.h @@ -0,0 +1,6 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/arch/amd64/gdtoa/gd_qnan.h b/lib/libc/arch/amd64/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..87eba8fb319 --- /dev/null +++ b/lib/libc/arch/amd64/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0xffc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0xfff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0xffff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0xffff diff --git a/lib/libc/arch/amd64/gdtoa/strtold.c b/lib/libc/arch/amd64/gdtoa/strtold.c new file mode 100644 index 00000000000..20b50655348 --- /dev/null +++ b/lib/libc/arch/amd64/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is an IEEE extended precision number. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorx(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/amd64/gen/Makefile.inc b/lib/libc/arch/amd64/gen/Makefile.inc index 6358bd86c61..85b61ffe27c 100644 --- a/lib/libc/arch/amd64/gen/Makefile.inc +++ b/lib/libc/arch/amd64/gen/Makefile.inc @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile.inc,v 1.4 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.5 2008/09/07 20:36:07 martynas Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c setjmp.S \ sigsetjmp.S +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \ fpsetround.S fpsetsticky.S diff --git a/lib/libc/arch/amd64/gen/fpclassifyl.c b/lib/libc/arch/amd64/gen/fpclassifyl.c new file mode 100644 index 00000000000..19940cdd53d --- /dev/null +++ b/lib/libc/arch/amd64/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/amd64/gen/isfinitel.c b/lib/libc/arch/amd64/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/amd64/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/amd64/gen/isinfl.c b/lib/libc/arch/amd64/gen/isinfl.c new file mode 100644 index 00000000000..862c82f97e7 --- /dev/null +++ b/lib/libc/arch/amd64/gen/isinfl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/amd64/gen/isnanl.c b/lib/libc/arch/amd64/gen/isnanl.c new file mode 100644 index 00000000000..4db08d62be6 --- /dev/null +++ b/lib/libc/arch/amd64/gen/isnanl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/amd64/gen/isnormall.c b/lib/libc/arch/amd64/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/amd64/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/arm/gdtoa/Makefile.inc b/lib/libc/arch/arm/gdtoa/Makefile.inc new file mode 100644 index 00000000000..b74c512bc69 --- /dev/null +++ b/lib/libc/arch/arm/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c diff --git a/lib/libc/arch/arm/gdtoa/arith.h b/lib/libc/arch/arm/gdtoa/arith.h new file mode 100644 index 00000000000..76539f82b9d --- /dev/null +++ b/lib/libc/arch/arm/gdtoa/arith.h @@ -0,0 +1,2 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 diff --git a/lib/libc/arch/arm/gdtoa/gd_qnan.h b/lib/libc/arch/arm/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..9c59e795bf6 --- /dev/null +++ b/lib/libc/arch/arm/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0xffffffff +#define d_QNAN0 0xffffffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0xffffffff +#define ld_QNAN1 0xffffffff +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0xffff +#define ldus_QNAN1 0xffff +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0xffff +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/hppa/gdtoa/Makefile.inc b/lib/libc/arch/hppa/gdtoa/Makefile.inc new file mode 100644 index 00000000000..b74c512bc69 --- /dev/null +++ b/lib/libc/arch/hppa/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c diff --git a/lib/libc/arch/hppa/gdtoa/arith.h b/lib/libc/arch/hppa/gdtoa/arith.h new file mode 100644 index 00000000000..e1954befb99 --- /dev/null +++ b/lib/libc/arch/hppa/gdtoa/arith.h @@ -0,0 +1,3 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/arch/hppa/gdtoa/gd_qnan.h b/lib/libc/arch/hppa/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..7956000880b --- /dev/null +++ b/lib/libc/arch/hppa/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fa00000 +#define d_QNAN0 0x7ff40000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff40000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff4 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/hppa64/gdtoa/Makefile.inc b/lib/libc/arch/hppa64/gdtoa/Makefile.inc new file mode 100644 index 00000000000..08b45b067ed --- /dev/null +++ b/lib/libc/arch/hppa64/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtorQ.c strtord.c diff --git a/lib/libc/arch/hppa64/gdtoa/arith.h b/lib/libc/arch/hppa64/gdtoa/arith.h new file mode 100644 index 00000000000..cf004954182 --- /dev/null +++ b/lib/libc/arch/hppa64/gdtoa/arith.h @@ -0,0 +1 @@ +/* TODO: put the proper definitions here. */ diff --git a/lib/libc/arch/hppa64/gdtoa/gd_qnan.h b/lib/libc/arch/hppa64/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..cf004954182 --- /dev/null +++ b/lib/libc/arch/hppa64/gdtoa/gd_qnan.h @@ -0,0 +1 @@ +/* TODO: put the proper definitions here. */ diff --git a/lib/libc/arch/hppa64/gdtoa/strtold.c b/lib/libc/arch/hppa64/gdtoa/strtold.c new file mode 100644 index 00000000000..3a5e322f01a --- /dev/null +++ b/lib/libc/arch/hppa64/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * uses quad precision, such as sparc64. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorQ(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/hppa64/gen/Makefile.inc b/lib/libc/arch/hppa64/gen/Makefile.inc index 91a4d2e8ffd..c167e7e0bda 100644 --- a/lib/libc/arch/hppa64/gen/Makefile.inc +++ b/lib/libc/arch/hppa64/gen/Makefile.inc @@ -1,10 +1,11 @@ -# $OpenBSD: Makefile.inc,v 1.3 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.4 2008/09/07 20:36:07 martynas Exp $ SRCS+= setjmp.S SRCS+= fabs.c frexp.c ldexp.c SRCS+= infinity.c nan.c setjmp.S SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= modf.c SRCS+= alloca.c diff --git a/lib/libc/arch/hppa64/gen/fpclassifyl.c b/lib/libc/arch/hppa64/gen/fpclassifyl.c new file mode 100644 index 00000000000..030e9c8aac4 --- /dev/null +++ b/lib/libc/arch/hppa64/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/hppa64/gen/isfinitel.c b/lib/libc/arch/hppa64/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/hppa64/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/hppa64/gen/isinfl.c b/lib/libc/arch/hppa64/gen/isinfl.c new file mode 100644 index 00000000000..c529a91cd2f --- /dev/null +++ b/lib/libc/arch/hppa64/gen/isinfl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/hppa64/gen/isnanl.c b/lib/libc/arch/hppa64/gen/isnanl.c new file mode 100644 index 00000000000..1838fcfe3fa --- /dev/null +++ b/lib/libc/arch/hppa64/gen/isnanl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_frachm != 0 || + p->ext_fraclm != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/hppa64/gen/isnormall.c b/lib/libc/arch/hppa64/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/hppa64/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/i386/gdtoa/Makefile.inc b/lib/libc/arch/i386/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9b47fc51d00 --- /dev/null +++ b/lib/libc/arch/i386/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorx.c diff --git a/lib/libc/arch/i386/gdtoa/arith.h b/lib/libc/arch/i386/gdtoa/arith.h new file mode 100644 index 00000000000..76539f82b9d --- /dev/null +++ b/lib/libc/arch/i386/gdtoa/arith.h @@ -0,0 +1,2 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 diff --git a/lib/libc/arch/i386/gdtoa/gd_qnan.h b/lib/libc/arch/i386/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..87eba8fb319 --- /dev/null +++ b/lib/libc/arch/i386/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0xffc00000 +#define d_QNAN0 0x0 +#define d_QNAN1 0xfff80000 +#define ld_QNAN0 0x0 +#define ld_QNAN1 0xc0000000 +#define ld_QNAN2 0xffff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x0 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0xc000 +#define ldus_QNAN4 0xffff diff --git a/lib/libc/arch/i386/gdtoa/strtold.c b/lib/libc/arch/i386/gdtoa/strtold.c new file mode 100644 index 00000000000..20b50655348 --- /dev/null +++ b/lib/libc/arch/i386/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is an IEEE extended precision number. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorx(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/i386/gen/Makefile.inc b/lib/libc/arch/i386/gen/Makefile.inc index bafaa0e9d86..863c28d0d18 100644 --- a/lib/libc/arch/i386/gen/Makefile.inc +++ b/lib/libc/arch/i386/gen/Makefile.inc @@ -1,7 +1,8 @@ -# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $ SRCS+= _setjmp.S alloca.S fabs.S infinity.c ldexp.c \ modf.S nan.c setjmp.S sigsetjmp.S +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \ fpsetround.S fpsetsticky.S SRCS+= divsi3.S fixdfsi.S fixunsdfsi.S udivsi3.S diff --git a/lib/libc/arch/i386/gen/fpclassifyl.c b/lib/libc/arch/i386/gen/fpclassifyl.c new file mode 100644 index 00000000000..19940cdd53d --- /dev/null +++ b/lib/libc/arch/i386/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/i386/gen/isfinitel.c b/lib/libc/arch/i386/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/i386/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/i386/gen/isinfl.c b/lib/libc/arch/i386/gen/isinfl.c new file mode 100644 index 00000000000..862c82f97e7 --- /dev/null +++ b/lib/libc/arch/i386/gen/isinfl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/i386/gen/isnanl.c b/lib/libc/arch/i386/gen/isnanl.c new file mode 100644 index 00000000000..4db08d62be6 --- /dev/null +++ b/lib/libc/arch/i386/gen/isnanl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/i386/gen/isnormall.c b/lib/libc/arch/i386/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/i386/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/m68k/gdtoa/Makefile.inc b/lib/libc/arch/m68k/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9b47fc51d00 --- /dev/null +++ b/lib/libc/arch/m68k/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorx.c diff --git a/lib/libc/arch/m68k/gdtoa/arith.h b/lib/libc/arch/m68k/gdtoa/arith.h new file mode 100644 index 00000000000..d16e11448ef --- /dev/null +++ b/lib/libc/arch/m68k/gdtoa/arith.h @@ -0,0 +1,2 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 diff --git a/lib/libc/arch/m68k/gdtoa/gd_qnan.h b/lib/libc/arch/m68k/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..a660b1f623b --- /dev/null +++ b/lib/libc/arch/m68k/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fffffff +#define d_QNAN0 0x7fffffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0x7fff0000 +#define ld_QNAN1 0xffffffff +#define ld_QNAN2 0xffffffff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7fff +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0xffff +#define ldus_QNAN4 0xffff diff --git a/lib/libc/arch/m68k/gdtoa/strtold.c b/lib/libc/arch/m68k/gdtoa/strtold.c new file mode 100644 index 00000000000..20b50655348 --- /dev/null +++ b/lib/libc/arch/m68k/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is an IEEE extended precision number. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorx(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/m68k/gen/Makefile.inc b/lib/libc/arch/m68k/gen/Makefile.inc index 698f4debf45..ae4b21ae368 100644 --- a/lib/libc/arch/m68k/gen/Makefile.inc +++ b/lib/libc/arch/m68k/gen/Makefile.inc @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.S \ modf.S nan.c setjmp.S sigsetjmp.S SRCS+= flt_rounds.S fpgetmask.S fpgetround.S fpgetsticky.S fpsetmask.S \ fpsetround.S fpsetsticky.S +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= adddf3.S addsf3.S ashlsi3.S ashrsi3.S cmpdf2.S cmpsf2.S divdf3.S \ divsf3.S divsi3.S extendsfdf2.S fixdfsi.S fixunsdfsi.S \ floatsidf.S lshlsi3.S lshrsi3.S modsi3.S muldf3.S mulsf3.S mulsi3.S \ diff --git a/lib/libc/arch/m68k/gen/fpclassifyl.c b/lib/libc/arch/m68k/gen/fpclassifyl.c new file mode 100644 index 00000000000..19940cdd53d --- /dev/null +++ b/lib/libc/arch/m68k/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/m68k/gen/isfinitel.c b/lib/libc/arch/m68k/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/m68k/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/m68k/gen/isinfl.c b/lib/libc/arch/m68k/gen/isinfl.c new file mode 100644 index 00000000000..862c82f97e7 --- /dev/null +++ b/lib/libc/arch/m68k/gen/isinfl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/m68k/gen/isnanl.c b/lib/libc/arch/m68k/gen/isnanl.c new file mode 100644 index 00000000000..4db08d62be6 --- /dev/null +++ b/lib/libc/arch/m68k/gen/isnanl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/m68k/gen/isnormall.c b/lib/libc/arch/m68k/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/m68k/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/m88k/gdtoa/Makefile.inc b/lib/libc/arch/m88k/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9b47fc51d00 --- /dev/null +++ b/lib/libc/arch/m88k/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorx.c diff --git a/lib/libc/arch/m88k/gdtoa/arith.h b/lib/libc/arch/m88k/gdtoa/arith.h new file mode 100644 index 00000000000..d16e11448ef --- /dev/null +++ b/lib/libc/arch/m88k/gdtoa/arith.h @@ -0,0 +1,2 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 diff --git a/lib/libc/arch/m88k/gdtoa/gd_qnan.h b/lib/libc/arch/m88k/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..a660b1f623b --- /dev/null +++ b/lib/libc/arch/m88k/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fffffff +#define d_QNAN0 0x7fffffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0x7fff0000 +#define ld_QNAN1 0xffffffff +#define ld_QNAN2 0xffffffff +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7fff +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0xffff +#define ldus_QNAN4 0xffff diff --git a/lib/libc/arch/m88k/gdtoa/strtold.c b/lib/libc/arch/m88k/gdtoa/strtold.c new file mode 100644 index 00000000000..20b50655348 --- /dev/null +++ b/lib/libc/arch/m88k/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is an IEEE extended precision number. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorx(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/m88k/gen/Makefile.inc b/lib/libc/arch/m88k/gen/Makefile.inc index 62bf28c6c51..a6d82239bed 100644 --- a/lib/libc/arch/m88k/gen/Makefile.inc +++ b/lib/libc/arch/m88k/gen/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:07 martynas Exp $ # $NetBSD: Makefile.inc,v 1.3 1995/04/10 21:09:06 jtc Exp $ #SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c @@ -9,6 +9,7 @@ SRCS+= _setjmp.S fabs.S frexp.c infinity.c ldexp.c nan.c SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= setjmp.S sigsetjmp.S SRCS+= modf.c diff --git a/lib/libc/arch/m88k/gen/fpclassifyl.c b/lib/libc/arch/m88k/gen/fpclassifyl.c new file mode 100644 index 00000000000..19940cdd53d --- /dev/null +++ b/lib/libc/arch/m88k/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/m88k/gen/isfinitel.c b/lib/libc/arch/m88k/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/m88k/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/m88k/gen/isinfl.c b/lib/libc/arch/m88k/gen/isinfl.c new file mode 100644 index 00000000000..862c82f97e7 --- /dev/null +++ b/lib/libc/arch/m88k/gen/isinfl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/m88k/gen/isnanl.c b/lib/libc/arch/m88k/gen/isnanl.c new file mode 100644 index 00000000000..4db08d62be6 --- /dev/null +++ b/lib/libc/arch/m88k/gen/isnanl.c @@ -0,0 +1,30 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + p->ext_frach &= ~0x80000000; /* clear normalization bit */ + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/m88k/gen/isnormall.c b/lib/libc/arch/m88k/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/m88k/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/mips64/gdtoa/Makefile.inc b/lib/libc/arch/mips64/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9a21a743db8 --- /dev/null +++ b/lib/libc/arch/mips64/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorQ.c diff --git a/lib/libc/arch/mips64/gdtoa/arith.h b/lib/libc/arch/mips64/gdtoa/arith.h new file mode 100644 index 00000000000..0b84f84f763 --- /dev/null +++ b/lib/libc/arch/mips64/gdtoa/arith.h @@ -0,0 +1,6 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/arch/mips64/gdtoa/gd_qnan.h b/lib/libc/arch/mips64/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..d65c5a53b7c --- /dev/null +++ b/lib/libc/arch/mips64/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fbfffff +#define d_QNAN0 0x7ff7ffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0x7fff8000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7fff +#define ldus_QNAN1 0x8000 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/mips64/gdtoa/strtold.c b/lib/libc/arch/mips64/gdtoa/strtold.c new file mode 100644 index 00000000000..3a5e322f01a --- /dev/null +++ b/lib/libc/arch/mips64/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * uses quad precision, such as sparc64. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorQ(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/mips64/gen/Makefile.inc b/lib/libc/arch/mips64/gen/Makefile.inc index 3063795496a..2098bcc4d93 100644 --- a/lib/libc/arch/mips64/gen/Makefile.inc +++ b/lib/libc/arch/mips64/gen/Makefile.inc @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile.inc,v 1.5 2008/07/25 08:00:01 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.6 2008/09/07 20:36:07 martynas Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.S modf.S nan.c SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= setjmp.S sigsetjmp.S SRCS+= alloca.c diff --git a/lib/libc/arch/mips64/gen/fpclassifyl.c b/lib/libc/arch/mips64/gen/fpclassifyl.c new file mode 100644 index 00000000000..030e9c8aac4 --- /dev/null +++ b/lib/libc/arch/mips64/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/mips64/gen/isfinitel.c b/lib/libc/arch/mips64/gen/isfinitel.c new file mode 100644 index 00000000000..c86b9309da4 --- /dev/null +++ b/lib/libc/arch/mips64/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/mips64/gen/isinfl.c b/lib/libc/arch/mips64/gen/isinfl.c new file mode 100644 index 00000000000..c529a91cd2f --- /dev/null +++ b/lib/libc/arch/mips64/gen/isinfl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/mips64/gen/isnanl.c b/lib/libc/arch/mips64/gen/isnanl.c new file mode 100644 index 00000000000..1838fcfe3fa --- /dev/null +++ b/lib/libc/arch/mips64/gen/isnanl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_frachm != 0 || + p->ext_fraclm != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/mips64/gen/isnormall.c b/lib/libc/arch/mips64/gen/isnormall.c new file mode 100644 index 00000000000..a8b4314afc9 --- /dev/null +++ b/lib/libc/arch/mips64/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/mips64/gen/nan.c b/lib/libc/arch/mips64/gen/nan.c index 62f2e1ad916..73ebf3b9a0f 100644 --- a/lib/libc/arch/mips64/gen/nan.c +++ b/lib/libc/arch/mips64/gen/nan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nan.c,v 1.1 2008/07/24 09:31:06 martynas Exp $ */ +/* $OpenBSD: nan.c,v 1.2 2008/09/07 20:36:07 martynas Exp $ */ /* Written by Martynas Venckus. Public Domain. */ @@ -9,7 +9,7 @@ /* bytes for qNaN on a mips64 (IEEE single format) */ char __nan[] __attribute__((__aligned__(sizeof(float)))) = #if BYTE_ORDER == BIG_ENDIAN - { 0x7f, 0xa0, 0, 0 }; + { 0x7f, 0xc0, 0, 0 }; #else /* BYTE_ORDER == BIG_ENDIAN */ - { 0, 0, 0xa0, 0x7f }; + { 0, 0, 0xc0, 0x7f }; #endif /* BYTE_ORDER == BIG_ENDIAN */ diff --git a/lib/libc/arch/powerpc/gdtoa/Makefile.inc b/lib/libc/arch/powerpc/gdtoa/Makefile.inc new file mode 100644 index 00000000000..b74c512bc69 --- /dev/null +++ b/lib/libc/arch/powerpc/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c diff --git a/lib/libc/arch/powerpc/gdtoa/arith.h b/lib/libc/arch/powerpc/gdtoa/arith.h new file mode 100644 index 00000000000..e1954befb99 --- /dev/null +++ b/lib/libc/arch/powerpc/gdtoa/arith.h @@ -0,0 +1,3 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/arch/powerpc/gdtoa/gd_qnan.h b/lib/libc/arch/powerpc/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..3327dc12024 --- /dev/null +++ b/lib/libc/arch/powerpc/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x7ff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/sh/gdtoa/Makefile.inc b/lib/libc/arch/sh/gdtoa/Makefile.inc new file mode 100644 index 00000000000..b74c512bc69 --- /dev/null +++ b/lib/libc/arch/sh/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c diff --git a/lib/libc/arch/sh/gdtoa/arith.h b/lib/libc/arch/sh/gdtoa/arith.h new file mode 100644 index 00000000000..ef6e7f4c433 --- /dev/null +++ b/lib/libc/arch/sh/gdtoa/arith.h @@ -0,0 +1,3 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Sudden_Underflow diff --git a/lib/libc/arch/sh/gdtoa/gd_qnan.h b/lib/libc/arch/sh/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..9bb017d51e0 --- /dev/null +++ b/lib/libc/arch/sh/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fbfffff +#define d_QNAN0 0xffffffff +#define d_QNAN1 0x7ff7ffff +#define ld_QNAN0 0xffffffff +#define ld_QNAN1 0x7ff7ffff +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0xffff +#define ldus_QNAN1 0xffff +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0x7ff7 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/sparc/gdtoa/Makefile.inc b/lib/libc/arch/sparc/gdtoa/Makefile.inc new file mode 100644 index 00000000000..9a21a743db8 --- /dev/null +++ b/lib/libc/arch/sparc/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:07 martynas Exp $ + +SRCS+= strtord.c strtorQ.c diff --git a/lib/libc/arch/sparc/gdtoa/arith.h b/lib/libc/arch/sparc/gdtoa/arith.h new file mode 100644 index 00000000000..e1954befb99 --- /dev/null +++ b/lib/libc/arch/sparc/gdtoa/arith.h @@ -0,0 +1,3 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/arch/sparc/gdtoa/gd_qnan.h b/lib/libc/arch/sparc/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..b25361613d6 --- /dev/null +++ b/lib/libc/arch/sparc/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fffffff +#define d_QNAN0 0x7fffffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0x7fffffff +#define ld_QNAN1 0xffffffff +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7fff +#define ldus_QNAN1 0xffff +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0xffff +#define ldus_QNAN4 0x0 diff --git a/lib/libc/arch/sparc/gdtoa/strtold.c b/lib/libc/arch/sparc/gdtoa/strtold.c new file mode 100644 index 00000000000..3a5e322f01a --- /dev/null +++ b/lib/libc/arch/sparc/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:07 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * uses quad precision, such as sparc64. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorQ(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/sparc/gen/Makefile.inc b/lib/libc/arch/sparc/gen/Makefile.inc index 85710859f3b..4d0fcc097c8 100644 --- a/lib/libc/arch/sparc/gen/Makefile.inc +++ b/lib/libc/arch/sparc/gen/Makefile.inc @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile.inc,v 1.6 2008/07/24 09:31:06 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.7 2008/09/07 20:36:08 martynas Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S SRCS+= alloca.c diff --git a/lib/libc/arch/sparc/gen/fpclassifyl.c b/lib/libc/arch/sparc/gen/fpclassifyl.c new file mode 100644 index 00000000000..d569ef90430 --- /dev/null +++ b/lib/libc/arch/sparc/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/sparc/gen/isfinitel.c b/lib/libc/arch/sparc/gen/isfinitel.c new file mode 100644 index 00000000000..f60c9f1af85 --- /dev/null +++ b/lib/libc/arch/sparc/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/sparc/gen/isinfl.c b/lib/libc/arch/sparc/gen/isinfl.c new file mode 100644 index 00000000000..8c11b447689 --- /dev/null +++ b/lib/libc/arch/sparc/gen/isinfl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/sparc/gen/isnanl.c b/lib/libc/arch/sparc/gen/isnanl.c new file mode 100644 index 00000000000..e5cfb5ae788 --- /dev/null +++ b/lib/libc/arch/sparc/gen/isnanl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_frachm != 0 || + p->ext_fraclm != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/sparc/gen/isnormall.c b/lib/libc/arch/sparc/gen/isnormall.c new file mode 100644 index 00000000000..91df6fe51d0 --- /dev/null +++ b/lib/libc/arch/sparc/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/sparc64/gdtoa/Makefile.inc b/lib/libc/arch/sparc64/gdtoa/Makefile.inc new file mode 100644 index 00000000000..4a6106dbaa6 --- /dev/null +++ b/lib/libc/arch/sparc64/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $ + +SRCS+= strtord.c strtorQ.c diff --git a/lib/libc/arch/sparc64/gdtoa/arith.h b/lib/libc/arch/sparc64/gdtoa/arith.h new file mode 100644 index 00000000000..0b84f84f763 --- /dev/null +++ b/lib/libc/arch/sparc64/gdtoa/arith.h @@ -0,0 +1,6 @@ +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers diff --git a/lib/libc/arch/sparc64/gdtoa/gd_qnan.h b/lib/libc/arch/sparc64/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..e9245803b2a --- /dev/null +++ b/lib/libc/arch/sparc64/gdtoa/gd_qnan.h @@ -0,0 +1,12 @@ +#define f_QNAN 0x7fffffff +#define d_QNAN0 0x7fffffff +#define d_QNAN1 0xffffffff +#define ld_QNAN0 0x7fffffff +#define ld_QNAN1 0xffffffff +#define ld_QNAN2 0xffffffff +#define ld_QNAN3 0xffffffff +#define ldus_QNAN0 0x7fff +#define ldus_QNAN1 0xffff +#define ldus_QNAN2 0xffff +#define ldus_QNAN3 0xffff +#define ldus_QNAN4 0xffff diff --git a/lib/libc/arch/sparc64/gdtoa/strtold.c b/lib/libc/arch/sparc64/gdtoa/strtold.c new file mode 100644 index 00000000000..ecbfd5507fa --- /dev/null +++ b/lib/libc/arch/sparc64/gdtoa/strtold.c @@ -0,0 +1,45 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * uses quad precision, such as sparc64. + */ + +#include <float.h> + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + long double result; + + strtorQ(s, sp, FLT_ROUNDS, &result); + return result; +} diff --git a/lib/libc/arch/sparc64/gen/Makefile.inc b/lib/libc/arch/sparc64/gen/Makefile.inc index 2fa31fd3071..8a7fafce703 100644 --- a/lib/libc/arch/sparc64/gen/Makefile.inc +++ b/lib/libc/arch/sparc64/gen/Makefile.inc @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile.inc,v 1.5 2008/07/24 09:31:07 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.6 2008/09/07 20:36:08 martynas Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.S nan.c SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c +SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c SRCS+= fixunsdfsi.S mul.S umul.S saveregs.S setjmp.S sigsetjmp.S SRCS+= alloca.c diff --git a/lib/libc/arch/sparc64/gen/fpclassifyl.c b/lib/libc/arch/sparc64/gen/fpclassifyl.c new file mode 100644 index 00000000000..d569ef90430 --- /dev/null +++ b/lib/libc/arch/sparc64/gen/fpclassifyl.c @@ -0,0 +1,44 @@ +/* $OpenBSD: fpclassifyl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +int +__fpclassifyl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + if (p->ext_exp == 0) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if (p->ext_exp == EXT_EXP_INFNAN) { + if (p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0) + return FP_INFINITE; + else + return FP_NAN; + } + + return FP_NORMAL; +} diff --git a/lib/libc/arch/sparc64/gen/isfinitel.c b/lib/libc/arch/sparc64/gen/isfinitel.c new file mode 100644 index 00000000000..f60c9f1af85 --- /dev/null +++ b/lib/libc/arch/sparc64/gen/isfinitel.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isfinitel.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isfinitel(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/sparc64/gen/isinfl.c b/lib/libc/arch/sparc64/gen/isinfl.c new file mode 100644 index 00000000000..8c11b447689 --- /dev/null +++ b/lib/libc/arch/sparc64/gen/isinfl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isinfl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isinfl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + p->ext_frach == 0 && p->ext_frachm == 0 && + p->ext_fraclm == 0 && p->ext_fracl == 0); +} diff --git a/lib/libc/arch/sparc64/gen/isnanl.c b/lib/libc/arch/sparc64/gen/isnanl.c new file mode 100644 index 00000000000..e5cfb5ae788 --- /dev/null +++ b/lib/libc/arch/sparc64/gen/isnanl.c @@ -0,0 +1,29 @@ +/* $OpenBSD: isnanl.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnanl(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp == EXT_EXP_INFNAN && + (p->ext_frach != 0 || p->ext_frachm != 0 || + p->ext_fraclm != 0 || p->ext_fracl != 0)); +} diff --git a/lib/libc/arch/sparc64/gen/isnormall.c b/lib/libc/arch/sparc64/gen/isnormall.c new file mode 100644 index 00000000000..91df6fe51d0 --- /dev/null +++ b/lib/libc/arch/sparc64/gen/isnormall.c @@ -0,0 +1,27 @@ +/* $OpenBSD: isnormall.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> + +int +__isnormall(long double e) +{ + struct ieee_ext *p = (struct ieee_ext *)&e; + + return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); +} diff --git a/lib/libc/arch/vax/gdtoa/Makefile.inc b/lib/libc/arch/vax/gdtoa/Makefile.inc new file mode 100644 index 00000000000..53e0b7aef69 --- /dev/null +++ b/lib/libc/arch/vax/gdtoa/Makefile.inc @@ -0,0 +1,3 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $ + +CFLAGS+= -DNO_HEX_FP diff --git a/lib/libc/arch/vax/gdtoa/arith.h b/lib/libc/arch/vax/gdtoa/arith.h new file mode 100644 index 00000000000..bd5c83a65ff --- /dev/null +++ b/lib/libc/arch/vax/gdtoa/arith.h @@ -0,0 +1,2 @@ +#define VAX +#define Arith_Kind_ASL 4 diff --git a/lib/libc/arch/vax/gdtoa/gd_qnan.h b/lib/libc/arch/vax/gdtoa/gd_qnan.h new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/lib/libc/arch/vax/gdtoa/gd_qnan.h diff --git a/lib/libc/arch/vax/gdtoa/hdtoa.c b/lib/libc/arch/vax/gdtoa/hdtoa.c new file mode 100644 index 00000000000..dc95c0e2eae --- /dev/null +++ b/lib/libc/arch/vax/gdtoa/hdtoa.c @@ -0,0 +1,224 @@ +/* $OpenBSD: hdtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/*- + * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/vaxfp.h> +#include <float.h> +#include <limits.h> +#include <math.h> + +#include "gdtoaimp.h" + +/* Strings values used by dtoa() */ +#define INFSTR "Infinity" +#define NANSTR "NaN" + +#define DBL_ADJ (DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4)) +#define LDBL_ADJ (LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4)) + +/* + * Round up the given digit string. If the digit string is fff...f, + * this procedure sets it to 100...0 and returns 1 to indicate that + * the exponent needs to be bumped. Otherwise, 0 is returned. + */ +static int +roundup(char *s0, int ndigits) +{ + char *s; + + for (s = s0 + ndigits - 1; *s == 0xf; s--) { + if (s == s0) { + *s = 1; + return (1); + } + *s = 0; + } + ++*s; + return (0); +} + +/* + * Round the given digit string to ndigits digits according to the + * current rounding mode. Note that this could produce a string whose + * value is not representable in the corresponding floating-point + * type. The exponent pointed to by decpt is adjusted if necessary. + */ +static void +dorounding(char *s0, int ndigits, int sign, int *decpt) +{ + int adjust = 0; /* do we need to adjust the exponent? */ + + switch (FLT_ROUNDS) { + case 0: /* toward zero */ + default: /* implementation-defined */ + break; + case 1: /* to nearest, halfway rounds to even */ + if ((s0[ndigits] > 8) || + (s0[ndigits] == 8 && s0[ndigits + 1] & 1)) + adjust = roundup(s0, ndigits); + break; + case 2: /* toward +inf */ + if (sign == 0) + adjust = roundup(s0, ndigits); + break; + case 3: /* toward -inf */ + if (sign != 0) + adjust = roundup(s0, ndigits); + break; + } + + if (adjust) + *decpt += 4; +} + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the + * first digit so that subsequent digits are aligned on nibble + * boundaries (before rounding). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + static const int sigfigs = (DBL_MANT_DIG + 3) / 4; + struct vax_d_floating *p = (struct vax_d_floating *)&d; + char *s, *s0; + int bufsize; + + *sign = p->dflt_sign; + + switch (fpclassify(d)) { + case FP_NORMAL: + *decpt = p->dflt_exp - DBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: + d *= 0x1p514; + *decpt = p->dflt_exp - (514 + DBL_ADJ); + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + case FP_NAN: + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + default: + abort(); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * For simplicity, we generate all the digits even if the + * caller has requested fewer. + */ + bufsize = (sigfigs > ndigits) ? sigfigs : ndigits; + s0 = rv_alloc(bufsize); + + /* + * We work from right to left, first adding any requested zero + * padding, then the least significant portion of the + * mantissa, followed by the most significant. The buffer is + * filled with the byte values 0x0 through 0xf, which are + * converted to xdigs[0x0] through xdigs[0xf] after the + * rounding phase. + */ + for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) + *s = 0; + for (; s > s0 + sigfigs - (DFLT_FRACLBITS / 4) - 1 && s > s0; s--) { + *s = p->dflt_fracl & 0xf; + p->dflt_fracl >>= 4; + } + for (; s > s0; s--) { + *s = p->dflt_fracm & 0xf; + p->dflt_fracm >>= 4; + } + for (; s > s0; s--) { + *s = p->dflt_frach & 0xf; + p->dflt_frach >>= 4; + } + + /* + * At this point, we have snarfed all the bits in the + * mantissa, with the possible exception of the highest-order + * (partial) nibble, which is dealt with by the next + * statement. We also tack on the implicit normalization bit. + */ + *s = p->dflt_frach | (1U << ((DBL_MANT_DIG - 1) % 4)); + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--) + ; + } + + if (sigfigs > ndigits && s0[ndigits] != 0) + dorounding(s0, ndigits, p->dflt_sign, decpt); + + s = s0 + ndigits; + if (rve != NULL) + *rve = s; + *s-- = '\0'; + for (; s >= s0; s--) + *s = xdigs[(unsigned int)*s]; + + return (s0); +} + +/* + * This is the long double version of __hdtoa(). + */ +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve)); +} diff --git a/lib/libc/arch/vax/gdtoa/strtof.c b/lib/libc/arch/vax/gdtoa/strtof.c new file mode 100644 index 00000000000..f0472c2558d --- /dev/null +++ b/lib/libc/arch/vax/gdtoa/strtof.c @@ -0,0 +1,67 @@ +/**************************************************************** + +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" + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ + static FPI fpi = { 24, 1-128-1-24+1, 255-128-1-24+1, 1, SI }; + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = 0; + break; + + case STRTOG_Normal: + u.L[0] = ((bits[0] & 0x0000ffff) << 16) | /* FracLo */ + ((bits[0] & 0x007f0000) >> 16) | /* FracHi */ + ((exp + 128 + 1 + 23) << 7); /* Exp */ + break; + + case STRTOG_Infinite: + u.L[0] = 0xffff7fff; + break; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x00008000L; + return u.f; + } diff --git a/lib/libc/gdtoa/Makefile.inc b/lib/libc/gdtoa/Makefile.inc new file mode 100644 index 00000000000..d32754336ec --- /dev/null +++ b/lib/libc/gdtoa/Makefile.inc @@ -0,0 +1,17 @@ +# $OpenBSD: Makefile.inc,v 1.1 2008/09/07 20:36:08 martynas Exp $ + +# gdtoa sources +.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa ${LIBCSRCDIR}/gdtoa + +CFLAGS+= -I${LIBCSRCDIR}/gdtoa +CFLAGS+= -I${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa + +CFLAGS+= -DINFNAN_CHECK +CFLAGS+= -DMULTIPLE_THREADS +CFLAGS+= -DNO_FENV_H + +SRCS+= dmisc.c dtoa.c gdtoa.c gethex.c gmisc.c hd_init.c hdtoa.c \ + hexnan.c ldtoa.c locks.c misc.c smisc.c strtod.c strtodg.c \ + strtof.c strtold.c sum.c ulp.c + +.include "${LIBCSRCDIR}/arch/${MACHINE_ARCH}/gdtoa/Makefile.inc" diff --git a/lib/libc/gdtoa/arithchk.c b/lib/libc/gdtoa/arithchk.c new file mode 100644 index 00000000000..3211aeda42c --- /dev/null +++ b/lib/libc/gdtoa/arithchk.c @@ -0,0 +1,183 @@ +/**************************************************************** +Copyright (C) 1997, 1998 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +/* Try to deduce arith.h from arithmetic properties. */ + +#include <stdio.h> + + static int dalign; + typedef struct +Akind { + char *name; + int kind; + } Akind; + + static Akind +IEEE_8087 = { "IEEE_8087", 1 }, +IEEE_MC68k = { "IEEE_MC68k", 2 }, +IBM = { "IBM", 3 }, +VAX = { "VAX", 4 }, +CRAY = { "CRAY", 5}; + + static Akind * +Lcheck() +{ + union { + double d; + long L[2]; + } u; + struct { + double d; + long L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(long))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + + static Akind * +icheck() +{ + union { + double d; + int L[2]; + } u; + struct { + double d; + int L; + } x[2]; + + if (sizeof(x) > 2*(sizeof(double) + sizeof(int))) + dalign = 1; + u.L[0] = u.L[1] = 0; + u.d = 1e13; + if (u.L[0] == 1117925532 && u.L[1] == -448790528) + return &IEEE_MC68k; + if (u.L[1] == 1117925532 && u.L[0] == -448790528) + return &IEEE_8087; + if (u.L[0] == -2065213935 && u.L[1] == 10752) + return &VAX; + if (u.L[0] == 1267827943 && u.L[1] == 704643072) + return &IBM; + return 0; + } + +char *emptyfmt = ""; /* avoid possible warning message with printf("") */ + + static Akind * +ccheck() +{ + union { + double d; + long L; + } u; + long Cray1; + + /* Cray1 = 4617762693716115456 -- without overflow on non-Crays */ + Cray1 = printf(emptyfmt) < 0 ? 0 : 4617762; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 693716; + if (printf(emptyfmt, Cray1) >= 0) + Cray1 = 1000000*Cray1 + 115456; + u.d = 1e13; + if (u.L == Cray1) + return &CRAY; + return 0; + } + + static int +fzcheck() +{ + double a, b; + int i; + + a = 1.; + b = .1; + for(i = 155;; b *= b, i >>= 1) { + if (i & 1) { + a *= b; + if (i == 1) + break; + } + } + b = a * a; + return b == 0.; + } + + int +main() +{ + Akind *a = 0; + int Ldef = 0; + FILE *f; + +#ifdef WRITE_ARITH_H /* for Symantec's buggy "make" */ + f = fopen("arith.h", "w"); + if (!f) { + printf("Cannot open arith.h\n"); + return 1; + } +#else + f = stdout; +#endif + + if (sizeof(double) == 2*sizeof(long)) + a = Lcheck(); + else if (sizeof(double) == 2*sizeof(int)) { + Ldef = 1; + a = icheck(); + } + else if (sizeof(double) == sizeof(long)) + a = ccheck(); + if (a) { + fprintf(f, "#define %s\n#define Arith_Kind_ASL %d\n", + a->name, a->kind); + if (Ldef) + fprintf(f, "#define Long int\n#define Intcast (int)(long)\n"); + if (dalign) + fprintf(f, "#define Double_Align\n"); + if (sizeof(char*) == 8) + fprintf(f, "#define X64_bit_pointers\n"); +#ifndef NO_LONG_LONG + if (sizeof(long long) < 8) +#endif + fprintf(f, "#define NO_LONG_LONG\n"); + if (a->kind <= 2 && fzcheck()) + fprintf(f, "#define Sudden_Underflow\n"); + return 0; + } + fprintf(f, "/* Unknown arithmetic */\n"); + return 1; + } diff --git a/lib/libc/gdtoa/dmisc.c b/lib/libc/gdtoa/dmisc.c new file mode 100644 index 00000000000..ce170c733bf --- /dev/null +++ b/lib/libc/gdtoa/dmisc.c @@ -0,0 +1,216 @@ +/**************************************************************** + +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; + } diff --git a/lib/libc/gdtoa/dtoa.c b/lib/libc/gdtoa/dtoa.c new file mode 100644 index 00000000000..e808cc1f4f3 --- /dev/null +++ b/lib/libc/gdtoa/dtoa.c @@ -0,0 +1,753 @@ +/**************************************************************** + +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" + +/* 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. + */ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + char * +dtoa +#ifdef KR_headers + (d, mode, ndigits, decpt, sign, rve) + double d; int mode, ndigits, *decpt, *sign; char **rve; +#else + (double d, int mode, int ndigits, int *decpt, int *sign, char **rve) +#endif +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + double d2, ds, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return nrv_alloc("Infinity", rve, 8); +#endif + return nrv_alloc("NaN", rve, 3); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if (( i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)) )!=0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (( j = 11 - hi0bits(word0(d2) & Frac_mask) )!=0) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (( j1 = -k )!=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (( j = b5 - m5 )!=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f )!=0) + i = 32 - i; +#else + if (( i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf )!=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + goto ret; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + ) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + } + accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS + keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + trimzeros: + while(*--s == '0'); + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; + } diff --git a/lib/libc/gdtoa/g_Qfmt.c b/lib/libc/gdtoa/g_Qfmt.c new file mode 100644 index 00000000000..2b9b3679963 --- /dev/null +++ b/lib/libc/gdtoa/g_Qfmt.c @@ -0,0 +1,114 @@ +/**************************************************************** + +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; unsigned bufsize; +#else +g_Qfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[4], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[3] = L[_0] & 0xffff; + bits[2] = L[_1]; + bits[1] = L[_2]; + bits[0] = L[_3]; + b = buf; + if ( (ex = (L[_0] & 0x7fff0000L) >> 16) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1] | bits[2] | bits[3]) + b = strcp(b, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + bits[3] |= 0x10000; + } + else if (bits[0] | bits[1] | bits[2] | bits[3]) { + i = STRTOG_Denormal; + ex = 1; + } + else { +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 112; + mode = 2; + if (ndig <= 0) { + if (bufsize < 48) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/lib/libc/gdtoa/g__fmt.c b/lib/libc/gdtoa/g__fmt.c new file mode 100644 index 00000000000..021ecfb5728 --- /dev/null +++ b/lib/libc/gdtoa/g__fmt.c @@ -0,0 +1,99 @@ +/**************************************************************** + +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) char *b; char *s; char *se; int decpt; ULong sign; +#else +g__fmt(char *b, char *s, char *se, int decpt, ULong sign) +#endif +{ + int i, j, k; + char *s0 = s; +#ifdef USE_LOCALE + char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + if (sign) + *b++ = '-'; + if (decpt <= -4 || decpt > se - s + 5) { + *b++ = *s++; + if (*s) { + *b++ = decimalpoint; + while((*b = *s++) !=0) + b++; + } + *b++ = 'e'; + /* sprintf(b, "%+.2d", decpt - 1); */ + if (--decpt < 0) { + *b++ = '-'; + decpt = -decpt; + } + else + *b++ = '+'; + for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10){} + for(;;) { + i = decpt / k; + *b++ = i + '0'; + if (--j <= 0) + break; + decpt -= i*k; + decpt *= 10; + } + *b = 0; + } + else if (decpt <= 0) { + *b++ = decimalpoint; + for(; decpt < 0; decpt++) + *b++ = '0'; + while((*b = *s++) !=0) + b++; + } + else { + while((*b = *s++) !=0) { + b++; + if (--decpt == 0 && *s) + *b++ = decimalpoint; + } + for(; decpt > 0; decpt--) + *b++ = '0'; + *b = 0; + } + freedtoa(s0); + return b; + } diff --git a/lib/libc/gdtoa/g_ddfmt.c b/lib/libc/gdtoa/g_ddfmt.c new file mode 100644 index 00000000000..7fc30578a90 --- /dev/null +++ b/lib/libc/gdtoa/g_ddfmt.c @@ -0,0 +1,154 @@ +/**************************************************************** + +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@acm.org). */ + +#include "gdtoaimp.h" +#include <string.h> + + char * +#ifdef KR_headers +g_ddfmt(buf, dd, ndig, bufsize) char *buf; double *dd; int ndig; unsigned bufsize; +#else +g_ddfmt(char *buf, double *dd, int ndig, unsigned bufsize) +#endif +{ + FPI fpi; + char *b, *s, *se; + ULong *L, bits0[4], *bits, *zx; + int bx, by, decpt, ex, ey, i, j, mode; + Bigint *x, *y, *z; + double ddx[2]; + + if (bufsize < 10 || bufsize < ndig + 8) + return 0; + + L = (ULong*)dd; + if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + nanret: + return strcp(buf, "NaN"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + if (L[2+_0] & 0xfffff || L[2+_1]) + goto nanret; + if ((L[_0] ^ L[2+_0]) & 0x80000000L) + goto nanret; /* Infinity - Infinity */ + } + infret: + b = buf; + if (L[_0] & 0x80000000L) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) { + L += 2; + if (L[_0] & 0xfffff || L[_1]) + goto nanret; + goto infret; + } + if (dd[0] + dd[1] == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & L[2+_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) { + ddx[1] = dd[0]; + ddx[0] = dd[1]; + dd = ddx; + L = (ULong*)dd; + } + z = d2b(dd[0], &ex, &bx); + if (dd[1] == 0.) + goto no_y; + x = z; + y = d2b(dd[1], &ey, &by); + if ( (i = ex - ey) !=0) { + if (i > 0) { + x = lshift(x, i); + ex = ey; + } + else + y = lshift(y, -i); + } + if ((L[_0] ^ L[2+_0]) & 0x80000000L) { + z = diff(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1 - z->sign; + } + else { + z = sum(x, y); + if (L[_0] & 0x80000000L) + z->sign = 1; + } + Bfree(x); + Bfree(y); + no_y: + bits = zx = z->x; + for(i = 0; !*zx; zx++) + i += 32; + i += lo0bits(zx); + if (i) { + rshift(z, i); + ex += i; + } + fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]); + if (fpi.nbits < 106) { + fpi.nbits = 106; + if (j < 3) { + for(i = 0; i <= j; i++) + bits0[i] = bits[i]; + while(i < 4) + bits0[i++] = 0; + bits = bits0; + } + } + mode = 2; + if (ndig <= 0) { + if (bufsize < (int)(fpi.nbits * .301029995664) + 10) { + Bfree(z); + return 0; + } + mode = 0; + } + fpi.emin = 1-1023-53+1; + fpi.emax = 2046-1023-106+1; + fpi.rounding = FPI_Round_near; + fpi.sudden_underflow = 0; + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + b = g__fmt(buf, s, se, decpt, z->sign); + Bfree(z); + return b; + } diff --git a/lib/libc/gdtoa/g_dfmt.c b/lib/libc/gdtoa/g_dfmt.c new file mode 100644 index 00000000000..db2636f6da9 --- /dev/null +++ b/lib/libc/gdtoa/g_dfmt.c @@ -0,0 +1,89 @@ +/**************************************************************** + +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" + + char* +#ifdef KR_headers +g_dfmt(buf, d, ndig, bufsize) char *buf; double *d; int ndig; unsigned bufsize; +#else +g_dfmt(char *buf, double *d, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)d; + sign = L[_0] & 0x80000000L; + if ((L[_0] & 0x7ff00000) == 0x7ff00000) { + /* Infinity or NaN */ + if (L[_0] & 0xfffff || L[_1]) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (L[_1] == 0 && (L[_0] ^ sign) == 0 /*d == 0.*/) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[_0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[_1]; + bits[1] = L[_0] & 0xfffff; + if ( (ex = (L[_0] >> 20) & 0x7ff) !=0) + bits[1] |= 0x100000; + else + ex = 1; + ex -= 0x3ff + 52; + mode = 2; + if (ndig <= 0) { + if (bufsize < 25) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/lib/libc/gdtoa/g_ffmt.c b/lib/libc/gdtoa/g_ffmt.c new file mode 100644 index 00000000000..612adfae382 --- /dev/null +++ b/lib/libc/gdtoa/g_ffmt.c @@ -0,0 +1,88 @@ +/**************************************************************** + +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" + + char* +#ifdef KR_headers +g_ffmt(buf, f, ndig, bufsize) char *buf; float *f; int ndig; unsigned bufsize; +#else +g_ffmt(char *buf, float *f, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, 0 }; + char *b, *s, *se; + ULong bits[1], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)f; + sign = L[0] & 0x80000000L; + if ((L[0] & 0x7f800000) == 0x7f800000) { + /* Infinity or NaN */ + if (L[0] & 0x7fffff) { + return strcp(buf, "NaN"); + } + b = buf; + if (sign) + *b++ = '-'; + return strcp(b, "Infinity"); + } + if (*f == 0.) { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (L[0] & 0x80000000L) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + bits[0] = L[0] & 0x7fffff; + if ( (ex = (L[0] >> 23) & 0xff) !=0) + bits[0] |= 0x800000; + else + ex = 1; + ex -= 0x7f + 23; + mode = 2; + if (ndig <= 0) { + if (bufsize < 16) + return 0; + mode = 0; + } + i = STRTOG_Normal; + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/lib/libc/gdtoa/g_xLfmt.c b/lib/libc/gdtoa/g_xLfmt.c new file mode 100644 index 00000000000..1bbc6e215ed --- /dev/null +++ b/lib/libc/gdtoa/g_xLfmt.c @@ -0,0 +1,108 @@ +/**************************************************************** + +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" + +#undef _0 +#undef _1 + +/* one or the other of IEEE_MC68k or IEEE_8087 should be #defined */ + +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define _2 2 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + char* +#ifdef KR_headers +g_xLfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xLfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], *L, sign; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (ULong*)V; + sign = L[_0] & 0x80000000L; + bits[1] = L[_1]; + bits[0] = L[_2]; + if ( (ex = (L[_0] >> 16) & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/lib/libc/gdtoa/g_xfmt.c b/lib/libc/gdtoa/g_xfmt.c new file mode 100644 index 00000000000..47a862d6bc7 --- /dev/null +++ b/lib/libc/gdtoa/g_xfmt.c @@ -0,0 +1,114 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (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 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + char* +#ifdef KR_headers +g_xfmt(buf, V, ndig, bufsize) char *buf; char *V; int ndig; unsigned bufsize; +#else +g_xfmt(char *buf, void *V, int ndig, unsigned bufsize) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 }; + char *b, *s, *se; + ULong bits[2], sign; + UShort *L; + int decpt, ex, i, mode; + + if (ndig < 0) + ndig = 0; + if (bufsize < ndig + 10) + return 0; + + L = (UShort *)V; + sign = L[_0] & 0x8000; + bits[1] = (L[_1] << 16) | L[_2]; + bits[0] = (L[_3] << 16) | L[_4]; + if ( (ex = L[_0] & 0x7fff) !=0) { + if (ex == 0x7fff) { + /* Infinity or NaN */ + if (bits[0] | bits[1]) + b = strcp(buf, "NaN"); + else { + b = buf; + if (sign) + *b++ = '-'; + b = strcp(b, "Infinity"); + } + return b; + } + i = STRTOG_Normal; + } + else if (bits[0] | bits[1]) { + i = STRTOG_Denormal; + ex = 1; + } + else { + b = buf; +#ifndef IGNORE_ZERO_SIGN + if (sign) + *b++ = '-'; +#endif + *b++ = '0'; + *b = 0; + return b; + } + ex -= 0x3fff + 63; + mode = 2; + if (ndig <= 0) { + if (bufsize < 32) + return 0; + mode = 0; + } + s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se); + return g__fmt(buf, s, se, decpt, sign); + } diff --git a/lib/libc/gdtoa/gdtoa.c b/lib/libc/gdtoa/gdtoa.c new file mode 100644 index 00000000000..8ff8cc587ea --- /dev/null +++ b/lib/libc/gdtoa/gdtoa.c @@ -0,0 +1,758 @@ +/**************************************************************** + +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 d, d2, ds, eps; + char *s, *s0; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + inex = 0; + kind = *kindp &= ~STRTOG_Inexact; + switch(kind & STRTOG_Retmask) { + case STRTOG_Zero: + goto ret_zero; + case STRTOG_Normal: + case STRTOG_Denormal: + break; + case STRTOG_Infinite: + *decpt = -32768; + return nrv_alloc("Infinity", rve, 8); + case STRTOG_NaN: + *decpt = -32768; + return nrv_alloc("NaN", rve, 3); + default: + return 0; + } + b = bitstob(bits, nbits = fpi->nbits, &bbits); + be0 = be; + if ( (i = trailz(b)) !=0) { + rshift(b, i); + be += i; + bbits -= i; + } + if (!b->wds) { + Bfree(b); + ret_zero: + *decpt = 1; + return nrv_alloc("0", rve, 1); + } + + dval(d) = b2d(b, &i); + i = be + bbits - 1; + word0(d) &= Frac_mask1; + word0(d) |= Exp_11; +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ +#ifdef IBM + i <<= 2; + i += j; +#endif + ds = (dval(d)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + + /* correct assumption about exponent range */ + if ((j = i) < 0) + j = -j; + if ((j -= 1077) > 0) + ds += j * 7e-17; + + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; +#ifdef IBM + j = be + bbits - 1; + if ( (j1 = j & 3) !=0) + dval(d) *= 1 << j1; + word0(d) += j << Exp_shift - 2 & Exp_mask; +#else + word0(d) += (be + bbits - 1) << Exp_shift; +#endif + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = (int)(nbits * .30103) + 3; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i); + + if ( (rdir = fpi->rounding - 1) !=0) { + if (rdir < 0) + rdir = 2; + if (kind & STRTOG_Neg) + rdir = 3 - rdir; + } + + /* Now rdir = 0 ==> round near, 1 ==> round up, 2 ==> round down. */ + + if (ilim >= 0 && ilim <= Quick_max && try_quick && !rdir +#ifndef IMPRECISE_INEXACT + && k == 0 +#endif + ) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = dval(d); +#ifdef IBM + if ( (j = 11 - hi0bits(word0(d) & Frac_mask)) !=0) + dval(d) /= 1 << j; +#endif + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + } + else { + ds = 1.; + if ( (j1 = -k) !=0) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = ds*0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = (Long)(dval(d)/ds); + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + if (ds - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + if ( (L = (Long)(dval(d)/ds)) !=0) + dval(d) -= L*ds; + *s++ = '0' + (int)L; + if (i == ilim) { + ds *= 0.5; + if (dval(d) > ds + dval(eps)) + goto bump_up; + else if (dval(d) < ds - dval(eps)) { + while(*--s == '0'){} + s++; + if (dval(d)) + inex = STRTOG_Inexlo; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = s0; + dval(d) = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++, dval(d) *= 10.) { + L = dval(d) / ds; + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (dval(d) == 0.) + break; + if (i == ilim) { + if (rdir) { + if (rdir == 1) + goto bump_up; + inex = STRTOG_Inexlo; + goto ret1; + } + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { + bump_up: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + else + inex = STRTOG_Inexlo; + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + mhi = mlo = 0; + if (leftright) { + if (mode < 2) { + i = nbits - bbits; + if (be - i++ < fpi->emin) + /* denormal */ + i = be - fpi->emin + 1; + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + } + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ( (j = b5 - m5) !=0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if (mode < 2) { + if (bbits == 1 && be0 > fpi->emin + 1) { + /* The special case */ + b2++; + s2++; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) !=0) + i = 32 - i; +#else + if ( (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) !=0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && mode > 2) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ + no_digits: + k = -1 - ndigits; + inex = STRTOG_Inexlo; + goto ret; + } + one_digit: + inex = STRTOG_Inexhi; + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, 1); + } + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(bits[0] & 1) && !rdir) { + if (dig == '9') + goto round_9_up; + if (j <= 0) { + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + } + else { + dig++; + inex = STRTOG_Inexhi; + } + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || j == 0 && !mode +#ifndef ROUND_BIASED + && !(bits[0] & 1) +#endif + ) { + if (rdir && (b->wds > 1 || b->x[0])) { + if (rdir == 2) { + inex = STRTOG_Inexlo; + goto accept; + } + while (cmp(S,mhi) > 0) { + *s++ = dig; + mhi1 = multadd(mhi, 10, 0); + if (mlo == mhi) + mlo = mhi1; + mhi = mhi1; + b = multadd(b, 10, 0); + dig = quorem(b,S) + '0'; + } + if (dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + goto accept; + } + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') + goto round_9_up; + inex = STRTOG_Inexhi; + } + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + accept: + *s++ = dig; + goto ret; + } + if (j1 > 0 && rdir != 2) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + inex = STRTOG_Inexhi; + goto roundoff; + } + inex = STRTOG_Inexhi; + *s++ = dig + 1; + goto ret; + } + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + + if (rdir) { + if (rdir == 2 || b->wds <= 1 && !b->x[0]) + goto chopzeros; + goto roundoff; + } + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || j == 0 && dig & 1) { + roundoff: + inex = STRTOG_Inexhi; + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + chopzeros: + if (b->wds > 1 || b->x[0]) + inex = STRTOG_Inexlo; + while(*--s == '0'){} + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + *kindp |= inex; + return s0; + } diff --git a/lib/libc/gdtoa/gdtoa.h b/lib/libc/gdtoa/gdtoa.h new file mode 100644 index 00000000000..ee6a9e53faf --- /dev/null +++ b/lib/libc/gdtoa/gdtoa.h @@ -0,0 +1,153 @@ +/**************************************************************** + +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 "."). */ + +#ifndef GDTOA_H_INCLUDED +#define GDTOA_H_INCLUDED + +#include "arith.h" + +#ifndef Long +#define Long long +#endif +#ifndef ULong +typedef unsigned Long ULong; +#endif +#ifndef UShort +typedef unsigned short UShort; +#endif + +#ifndef ANSI +#ifdef KR_headers +#define ANSI(x) () +#define Void /*nothing*/ +#else +#define ANSI(x) x +#define Void void +#endif +#endif /* ANSI */ + +#ifndef CONST +#ifdef KR_headers +#define CONST /* blank */ +#else +#define CONST const +#endif +#endif /* CONST */ + + enum { /* return values from strtodg */ + STRTOG_Zero = 0, + STRTOG_Normal = 1, + STRTOG_Denormal = 2, + STRTOG_Infinite = 3, + STRTOG_NaN = 4, + STRTOG_NaNbits = 5, + STRTOG_NoNumber = 6, + STRTOG_Retmask = 7, + + /* The following may be or-ed into one of the above values. */ + + STRTOG_Neg = 0x08, + STRTOG_Inexlo = 0x10, + STRTOG_Inexhi = 0x20, + STRTOG_Inexact = 0x30, + STRTOG_Underflow= 0x40, + STRTOG_Overflow = 0x80 + }; + + typedef struct +FPI { + int nbits; + int emin; + int emax; + int rounding; + int sudden_underflow; + } FPI; + +enum { /* FPI.rounding values: same as FLT_ROUNDS */ + FPI_Round_zero = 0, + FPI_Round_near = 1, + FPI_Round_up = 2, + FPI_Round_down = 3 + }; + +#ifdef __cplusplus +extern "C" { +#endif + +extern char* dtoa ANSI((double d, int mode, int ndigits, int *decpt, + int *sign, char **rve)); +extern char* gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); +extern void freedtoa ANSI((char*)); +extern float strtof ANSI((CONST char *, char **)); +extern double strtod ANSI((CONST char *, char **)); +extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*)); + +extern char* g_ddfmt ANSI((char*, double*, int, unsigned)); +extern char* g_dfmt ANSI((char*, double*, int, unsigned)); +extern char* g_ffmt ANSI((char*, float*, int, unsigned)); +extern char* g_Qfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xfmt ANSI((char*, void*, int, unsigned)); +extern char* g_xLfmt ANSI((char*, void*, int, unsigned)); + +extern int strtoId ANSI((CONST char*, char**, double*, double*)); +extern int strtoIdd ANSI((CONST char*, char**, double*, double*)); +extern int strtoIf ANSI((CONST char*, char**, float*, float*)); +extern int strtoIQ ANSI((CONST char*, char**, void*, void*)); +extern int strtoIx ANSI((CONST char*, char**, void*, void*)); +extern int strtoIxL ANSI((CONST char*, char**, void*, void*)); +extern int strtord ANSI((CONST char*, char**, int, double*)); +extern int strtordd ANSI((CONST char*, char**, int, double*)); +extern int strtorf ANSI((CONST char*, char**, int, float*)); +extern int strtorQ ANSI((CONST char*, char**, int, void*)); +extern int strtorx ANSI((CONST char*, char**, int, void*)); +extern int strtorxL ANSI((CONST char*, char**, int, void*)); +#if 1 +extern int strtodI ANSI((CONST char*, char**, double*)); +extern int strtopd ANSI((CONST char*, char**, double*)); +extern int strtopdd ANSI((CONST char*, char**, double*)); +extern int strtopf ANSI((CONST char*, char**, float*)); +extern int strtopQ ANSI((CONST char*, char**, void*)); +extern int strtopx ANSI((CONST char*, char**, void*)); +extern int strtopxL ANSI((CONST char*, char**, void*)); +#else +#define strtopd(s,se,x) strtord(s,se,1,x) +#define strtopdd(s,se,x) strtordd(s,se,1,x) +#define strtopf(s,se,x) strtorf(s,se,1,x) +#define strtopQ(s,se,x) strtorQ(s,se,1,x) +#define strtopx(s,se,x) strtorx(s,se,1,x) +#define strtopxL(s,se,x) strtorxL(s,se,1,x) +#endif + +#ifdef __cplusplus +} +#endif +#endif /* GDTOA_H_INCLUDED */ diff --git a/lib/libc/gdtoa/gdtoaimp.h b/lib/libc/gdtoa/gdtoaimp.h new file mode 100644 index 00000000000..e850dae5a55 --- /dev/null +++ b/lib/libc/gdtoa/gdtoaimp.h @@ -0,0 +1,659 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* This is a variation on dtoa.c that converts arbitary binary + floating-point formats to and from decimal notation. It uses + double-precision arithmetic internally, so there are still + various #ifdefs that adapt the calculations to the native + double-precision arithmetic (any of IEEE, VAX D_floating, + or IBM mainframe arithmetic). + + Please send bug reports to David M. Gay (dmg at acm dot org, + with " at " changed at "@" and " dot " changed to "."). + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. When converting IEEE double precision values, the + * longest string gdtoa can return is about 751 bytes long. For + * conversions by strtod of strings of 800 digits and all gdtoa + * conversions of IEEE doubles in single-threaded executions with + * 8-byte pointers, PRIVATE_MEM >= 7400 appears to suffice; with + * 4-byte pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtodg also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits (optionally + * preceded by 0x or 0X) and spaces; if there is only one string + * of hexadecimal digits, it is taken for the fraction bits of the + * resulting NaN; if there are two or more strings of hexadecimal + * digits, each string is assigned to the next available sequence + * of 32-bit words of fractions bits (starting with the most + * significant), right-aligned in each sequence. + * Unless GDTOA_NON_PEDANTIC_NANCHECK is #defined, input "NaN(...)" + * is consumed even when ... has the wrong form (in which case the + * "(...)" is consumed but ignored). + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define IMPRECISE_INEXACT if you do not care about the setting of + * the STRTOG_Inexact bits in the special case of doing IEEE double + * precision conversions (which could also be done by the strtog in + * dtoa.c). + * #define NO_HEX_FP to disable recognition of C9x's hexadecimal + * floating-point constants. + * #define -DNO_ERRNO to suppress setting errno (in strtod.c and + * strtodg.c). + * #define NO_STRING_H to use private versions of memcpy. + * On some K&R systems, it may also be necessary to + * #define DECLARE_SIZE_T in this case. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + */ + +#ifndef GDTOAIMP_H_INCLUDED +#define GDTOAIMP_H_INCLUDED + +#define Long int + +#include "gdtoa.h" +#include "gd_qnan.h" + +#ifdef DEBUG +#include "stdio.h" +#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} +#endif + +#include "stdlib.h" +#include "string.h" + +#ifdef KR_headers +#define Char char +#else +#define Char void +#endif + +#ifdef MALLOC +extern Char *MALLOC ANSI((size_t)); +#else +#define MALLOC malloc +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_MC68k +#define IEEE_Arith +#endif +#ifdef IEEE_8087 +#define IEEE_Arith +#endif + +#include "errno.h" +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#define DBL_MAX 1.7976931348623157e+308 +#endif + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#define n_bigtens 2 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +#endif /* Bad_float_h */ + +#ifdef IEEE_Arith +#define Scale_Bit 0x10 +#define n_bigtens 5 +#endif + +#ifdef IBM +#define n_bigtens 3 +#endif + +#ifdef VAX +#define n_bigtens 2 +#endif + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +#define dval(x) x +#ifdef IEEE_8087 +#define word0(x) ((ULong *)&x)[1] +#define word1(x) ((ULong *)&x)[0] +#else +#define word0(x) ((ULong *)&x)[0] +#define word1(x) ((ULong *)&x)[1] +#endif +#else /* !YES_ALIAS */ +#ifdef IEEE_8087 +#define word0(x) ((U*)&x)->L[1] +#define word1(x) ((U*)&x)->L[0] +#else +#define word0(x) ((U*)&x)->L[0] +#define word1(x) ((U*)&x)->L[1] +#endif +#define dval(x) ((U*)&x)->d +#endif /* YES_ALIAS */ + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_8087) + defined(VAX) +#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ +((unsigned short *)a)[0] = (unsigned short)c, a++) +#else +#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ +((unsigned short *)a)[1] = (unsigned short)c, a++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#else /* ifndef IEEE_Arith */ +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +#ifdef KR_headers +extern double rnd_prod(), rnd_quot(); +#else +extern double rnd_prod(double, double), rnd_quot(double, double); +#endif +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#undef Pack_16 +#ifndef Pack_32 +#define Pack_32 +#endif + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +#define Pack_16 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#ifdef Pack_32 +#define ULbits 32 +#define kshift 5 +#define kmask 31 +#define ALL_ON 0xffffffff +#else +#define ULbits 16 +#define kshift 4 +#define kmask 15 +#define ALL_ON 0xffff +#endif + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#else +#include "thread_private.h" +extern void *__dtoa_locks[]; +#define ACQUIRE_DTOA_LOCK(n) _MUTEX_LOCK(&__dtoa_locks[n]) +#define FREE_DTOA_LOCK(n) _MUTEX_UNLOCK(&__dtoa_locks[n]) +#endif + +#define Kmax 15 + + struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; + }; + + typedef struct Bigint Bigint; + +#ifdef NO_STRING_H +#ifdef DECLARE_SIZE_T +typedef unsigned int size_t; +#endif +extern void memcpy_D2A ANSI((void*, const void*, size_t)); +#define Bcopy(x,y) memcpy_D2A(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#else /* !NO_STRING_H */ +#define Bcopy(x,y) memcpy(&x->sign,&y->sign,y->wds*sizeof(ULong) + 2*sizeof(int)) +#endif /* NO_STRING_H */ + +#define dtoa __dtoa +#define gdtoa __gdtoa +#define freedtoa __freedtoa +#define strtodg __strtodg +#define g_ddfmt __g_ddfmt +#define g_dfmt __g_dfmt +#define g_ffmt __g_ffmt +#define g_Qfmt __g_Qfmt +#define g_xfmt __g_xfmt +#define g_xLfmt __g_xLfmt +#define strtoId __strtoId +#define strtoIdd __strtoIdd +#define strtoIf __strtoIf +#define strtoIQ __strtoIQ +#define strtoIx __strtoIx +#define strtoIxL __strtoIxL +#define strtord __strtord +#define strtordd __strtordd +#define strtorf __strtorf +#define strtorQ __strtorQ +#define strtorx __strtorx +#define strtorxL __strtorxL +#define strtodI __strtodI +#define strtopd __strtopd +#define strtopdd __strtopdd +#define strtopf __strtopf +#define strtopQ __strtopQ +#define strtopx __strtopx +#define strtopxL __strtopxL + +#define Balloc __Balloc_D2A +#define Bfree __Bfree_D2A +#define ULtoQ __ULtoQ_D2A +#define ULtof __ULtof_D2A +#define ULtod __ULtod_D2A +#define ULtodd __ULtodd_D2A +#define ULtox __ULtox_D2A +#define ULtoxL __ULtoxL_D2A +#define any_on __any_on_D2A +#define b2d __b2d_D2A +#define bigtens __bigtens_D2A +#define cmp __cmp_D2A +#define copybits __copybits_D2A +#define d2b __d2b_D2A +#define decrement __decrement_D2A +#define diff __diff_D2A +#define dtoa_result __dtoa_result_D2A +#define g__fmt __g__fmt_D2A +#define gethex __gethex_D2A +#define hexdig __hexdig_D2A +#define hexnan __hexnan_D2A +#define hi0bits __hi0bits_D2A +#define hi0bits_D2A __hi0bits_D2A +#define i2b __i2b_D2A +#define increment __increment_D2A +#define lo0bits __lo0bits_D2A +#define lshift __lshift_D2A +#define match __match_D2A +#define mult __mult_D2A +#define multadd __multadd_D2A +#define nrv_alloc __nrv_alloc_D2A +#define pow5mult __pow5mult_D2A +#define quorem __quorem_D2A +#define ratio __ratio_D2A +#define rshift __rshift_D2A +#define rv_alloc __rv_alloc_D2A +#define s2b __s2b_D2A +#define set_ones __set_ones_D2A +#define strcp __strcp_D2A +#define strtoIg __strtoIg_D2A +#define sum __sum_D2A +#define tens __tens_D2A +#define tinytens __tinytens_D2A +#define tinytens __tinytens_D2A +#define trailz __trailz_D2A +#define ulp __ulp_D2A + + extern char *dtoa_result; + extern CONST double bigtens[], tens[], tinytens[]; + extern unsigned char hexdig[]; + + extern Bigint *Balloc ANSI((int)); + extern void Bfree ANSI((Bigint*)); + extern void ULtof ANSI((ULong*, ULong*, Long, int)); + extern void ULtod ANSI((ULong*, ULong*, Long, int)); + extern void ULtodd ANSI((ULong*, ULong*, Long, int)); + extern void ULtoQ ANSI((ULong*, ULong*, Long, int)); + extern void ULtox ANSI((UShort*, ULong*, Long, int)); + extern void ULtoxL ANSI((ULong*, ULong*, Long, int)); + extern ULong any_on ANSI((Bigint*, int)); + extern double b2d ANSI((Bigint*, int*)); + extern int cmp ANSI((Bigint*, Bigint*)); + extern void copybits ANSI((ULong*, int, Bigint*)); + extern Bigint *d2b ANSI((double, int*, int*)); + extern int decrement ANSI((Bigint*)); + extern Bigint *diff ANSI((Bigint*, Bigint*)); + extern char *dtoa ANSI((double d, int mode, int ndigits, + int *decpt, int *sign, char **rve)); + extern char *gdtoa ANSI((FPI *fpi, int be, ULong *bits, int *kindp, + int mode, int ndigits, int *decpt, char **rve)); + extern char *g__fmt ANSI((char*, char*, char*, int, ULong)); + extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int)); + extern void hexdig_init_D2A(Void); + extern int hexnan ANSI((CONST char**, FPI*, ULong*)); + extern int hi0bits_D2A ANSI((ULong)); + extern Bigint *i2b ANSI((int)); + extern Bigint *increment ANSI((Bigint*)); + extern int lo0bits ANSI((ULong*)); + extern Bigint *lshift ANSI((Bigint*, int)); + extern int match ANSI((CONST char**, char*)); + extern Bigint *mult ANSI((Bigint*, Bigint*)); + extern Bigint *multadd ANSI((Bigint*, int, int)); + extern char *nrv_alloc ANSI((char*, char **, int)); + extern Bigint *pow5mult ANSI((Bigint*, int)); + extern int quorem ANSI((Bigint*, Bigint*)); + extern double ratio ANSI((Bigint*, Bigint*)); + extern void rshift ANSI((Bigint*, int)); + extern char *rv_alloc ANSI((int)); + extern Bigint *s2b ANSI((CONST char*, int, int, ULong)); + extern Bigint *set_ones ANSI((Bigint*, int)); + extern char *strcp ANSI((char*, const char*)); + extern int strtoIg ANSI((CONST char*, char**, FPI*, Long*, Bigint**, int*)); + extern double strtod ANSI((const char *s00, char **se)); + extern Bigint *sum ANSI((Bigint*, Bigint*)); + extern int trailz ANSI((Bigint*)); + extern double ulp ANSI((double)); + +#ifdef __cplusplus +} +#endif +/* + * NAN_WORD0 and NAN_WORD1 are only referenced in strtod.c. Prior to + * 20050115, they used to be hard-wired here (to 0x7ff80000 and 0, + * respectively), but now are determined by compiling and running + * qnan.c to generate gd_qnan.h, which specifies d_QNAN0 and d_QNAN1. + * Formerly gdtoaimp.h recommended supplying suitable -DNAN_WORD0=... + * and -DNAN_WORD1=... values if necessary. This should still work. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + */ +#ifdef IEEE_Arith +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN0 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN1 +#endif +#else +#define _0 1 +#define _1 0 +#ifndef NAN_WORD0 +#define NAN_WORD0 d_QNAN1 +#endif +#ifndef NAN_WORD1 +#define NAN_WORD1 d_QNAN0 +#endif +#endif +#else +#undef INFNAN_CHECK +#endif + +#undef SI +#ifdef Sudden_Underflow +#define SI 1 +#else +#define SI 0 +#endif + +#endif /* GDTOAIMP_H_INCLUDED */ diff --git a/lib/libc/gdtoa/gethex.c b/lib/libc/gdtoa/gethex.c new file mode 100644 index 00000000000..f130fd53112 --- /dev/null +++ b/lib/libc/gdtoa/gethex.c @@ -0,0 +1,250 @@ +/**************************************************************** + +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 + + int +#ifdef KR_headers +gethex(sp, fpi, exp, bp, sign) + CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; +#else +gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign) +#endif +{ + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + int esign, havedig, irv, k, n, nbits, up, zret; + ULong L, lostbits, *x; + Long e, e1; +#ifdef USE_LOCALE + unsigned char decimalpoint = *localeconv()->decimal_point; +#else +#define decimalpoint '.' +#endif + + if (!hexdig['0']) + hexdig_init_D2A(); + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') + havedig++; + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (!hexdig[*s]) { + zret = 1; + if (*s != decimalpoint) + goto pcheck; + decpt = ++s; + if (!hexdig[*s]) + goto pcheck; + while(*s == '0') + s++; + if (hexdig[*s]) + zret = 0; + havedig = 1; + s0 = s; + } + while(hexdig[*s]) + s++; + if (*s == decimalpoint && !decpt) { + decpt = ++s; + while(hexdig[*s]) + s++; + } + if (decpt) + e = -(((Long)(s-decpt)) << 2); + pcheck: + s1 = s; + switch(*s) { + case 'p': + case 'P': + esign = 0; + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) + e1 = 10*e1 + n - 0x10; + if (esign) + e1 = -e1; + e += e1; + } + *sp = (char*)s; + if (zret) { + if (!havedig) + *sp = s0 - 1; + return STRTOG_Zero; + } + n = s1 - s0 - 1; + for(k = 0; n > 7; n >>= 1) + k++; + b = Balloc(k); + x = b->x; + n = 0; + L = 0; + while(s1 > s0) { + if (*--s1 == decimalpoint) + continue; + if (n == 32) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = 32*n - hi0bits(L); + nbits = fpi->nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 1 && any_on(b,k-1)) + lostbits = 3; + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > fpi->emax) { + ovfl: + Bfree(b); + *bp = 0; + return STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; + } + irv = STRTOG_Normal; + if (e < fpi->emin) { + irv = STRTOG_Denormal; + n = fpi->emin - e; + if (n >= nbits) { + switch (fpi->rounding) { + case FPI_Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) + goto one_bit; + break; + case FPI_Round_up: + if (!sign) + goto one_bit; + break; + case FPI_Round_down: + if (sign) { + one_bit: + *exp = fpi->emin; + x[0] = b->wds = 1; + *bp = b; + return STRTOG_Denormal | STRTOG_Inexhi + | STRTOG_Underflow; + } + } + Bfree(b); + *bp = 0; + return STRTOG_Zero | STRTOG_Inexlo | STRTOG_Underflow; + } + k = n - 1; + if (lostbits) + lostbits = 1; + else if (k > 0) + lostbits = any_on(b,k); + if (x[k>>kshift] & 1 << (k & kmask)) + lostbits |= 2; + nbits -= n; + rshift(b,n); + e = fpi->emin; + } + if (lostbits) { + up = 0; + switch(fpi->rounding) { + case FPI_Round_zero: + break; + case FPI_Round_near: + if (lostbits & 2 + && (lostbits & 1) | x[0] & 1) + up = 1; + break; + case FPI_Round_up: + up = 1 - sign; + break; + case FPI_Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (irv == STRTOG_Denormal) { + if (nbits == fpi->nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) + irv = STRTOG_Normal; + } + else if (b->wds > k + || (n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n) { + rshift(b,1); + if (++e > fpi->emax) + goto ovfl; + } + irv |= STRTOG_Inexhi; + } + else + irv |= STRTOG_Inexlo; + } + *bp = b; + *exp = e; + return irv; + } diff --git a/lib/libc/gdtoa/gmisc.c b/lib/libc/gdtoa/gmisc.c new file mode 100644 index 00000000000..8270ef94479 --- /dev/null +++ b/lib/libc/gdtoa/gmisc.c @@ -0,0 +1,86 @@ +/**************************************************************** + +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" + + void +#ifdef KR_headers +rshift(b, k) Bigint *b; int k; +#else +rshift(Bigint *b, int k) +#endif +{ + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = ULbits - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & ALL_ON; + y = *x++ >> k; + } + if ((*x1 = y) !=0) + x1++; + } + else + while(x < xe) + *x1++ = *x++; + } + if ((b->wds = x1 - b->x) == 0) + b->x[0] = 0; + } + + int +#ifdef KR_headers +trailz(b) Bigint *b; +#else +trailz(Bigint *b) +#endif +{ + ULong L, *x, *xe; + int n = 0; + + x = b->x; + xe = x + b->wds; + for(n = 0; x < xe && !*x; x++) + n += ULbits; + if (x < xe) { + L = *x; + n += lo0bits(&L); + } + return n; + } diff --git a/lib/libc/gdtoa/hd_init.c b/lib/libc/gdtoa/hd_init.c new file mode 100644 index 00000000000..fa6e18dee8f --- /dev/null +++ b/lib/libc/gdtoa/hd_init.c @@ -0,0 +1,55 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + unsigned char hexdig[256]; + + static void +#ifdef KR_headers +htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; +#else +htinit(unsigned char *h, unsigned char *s, int inc) +#endif +{ + int i, j; + for(i = 0; (j = s[i]) !=0; i++) + h[j] = i + inc; + } + + void +hexdig_init_D2A(Void) +{ +#define USC (unsigned char *) + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); + } diff --git a/lib/libc/gdtoa/hdtoa.c b/lib/libc/gdtoa/hdtoa.c new file mode 100644 index 00000000000..f841538a300 --- /dev/null +++ b/lib/libc/gdtoa/hdtoa.c @@ -0,0 +1,328 @@ +/* $OpenBSD: hdtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/*- + * Copyright (c) 2004, 2005 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <float.h> +#include <limits.h> +#include <math.h> + +#include "gdtoaimp.h" + +/* Strings values used by dtoa() */ +#define INFSTR "Infinity" +#define NANSTR "NaN" + +#define DBL_ADJ (DBL_MAX_EXP - 2 + ((DBL_MANT_DIG - 1) % 4)) +#define LDBL_ADJ (LDBL_MAX_EXP - 2 + ((LDBL_MANT_DIG - 1) % 4)) + +/* + * Round up the given digit string. If the digit string is fff...f, + * this procedure sets it to 100...0 and returns 1 to indicate that + * the exponent needs to be bumped. Otherwise, 0 is returned. + */ +static int +roundup(char *s0, int ndigits) +{ + char *s; + + for (s = s0 + ndigits - 1; *s == 0xf; s--) { + if (s == s0) { + *s = 1; + return (1); + } + *s = 0; + } + ++*s; + return (0); +} + +/* + * Round the given digit string to ndigits digits according to the + * current rounding mode. Note that this could produce a string whose + * value is not representable in the corresponding floating-point + * type. The exponent pointed to by decpt is adjusted if necessary. + */ +static void +dorounding(char *s0, int ndigits, int sign, int *decpt) +{ + int adjust = 0; /* do we need to adjust the exponent? */ + + switch (FLT_ROUNDS) { + case 0: /* toward zero */ + default: /* implementation-defined */ + break; + case 1: /* to nearest, halfway rounds to even */ + if ((s0[ndigits] > 8) || + (s0[ndigits] == 8 && s0[ndigits + 1] & 1)) + adjust = roundup(s0, ndigits); + break; + case 2: /* toward +inf */ + if (sign == 0) + adjust = roundup(s0, ndigits); + break; + case 3: /* toward -inf */ + if (sign != 0) + adjust = roundup(s0, ndigits); + break; + } + + if (adjust) + *decpt += 4; +} + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation chooses the + * first digit so that subsequent digits are aligned on nibble + * boundaries (before rounding). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + static const int sigfigs = (DBL_MANT_DIG + 3) / 4; + struct ieee_double *p = (struct ieee_double *)&d; + char *s, *s0; + int bufsize; + + *sign = p->dbl_sign; + + switch (fpclassify(d)) { + case FP_NORMAL: + *decpt = p->dbl_exp - DBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: + d *= 0x1p514; + *decpt = p->dbl_exp - (514 + DBL_ADJ); + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + case FP_NAN: + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + default: + abort(); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * For simplicity, we generate all the digits even if the + * caller has requested fewer. + */ + bufsize = (sigfigs > ndigits) ? sigfigs : ndigits; + s0 = rv_alloc(bufsize); + + /* + * We work from right to left, first adding any requested zero + * padding, then the least significant portion of the + * mantissa, followed by the most significant. The buffer is + * filled with the byte values 0x0 through 0xf, which are + * converted to xdigs[0x0] through xdigs[0xf] after the + * rounding phase. + */ + for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) + *s = 0; + for (; s > s0 + sigfigs - (DBL_FRACLBITS / 4) - 1 && s > s0; s--) { + *s = p->dbl_fracl & 0xf; + p->dbl_fracl >>= 4; + } + for (; s > s0; s--) { + *s = p->dbl_frach & 0xf; + p->dbl_frach >>= 4; + } + + /* + * At this point, we have snarfed all the bits in the + * mantissa, with the possible exception of the highest-order + * (partial) nibble, which is dealt with by the next + * statement. We also tack on the implicit normalization bit. + */ + *s = p->dbl_frach | (1U << ((DBL_MANT_DIG - 1) % 4)); + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--) + ; + } + + if (sigfigs > ndigits && s0[ndigits] != 0) + dorounding(s0, ndigits, p->dbl_sign, decpt); + + s = s0 + ndigits; + if (rve != NULL) + *rve = s; + *s-- = '\0'; + for (; s >= s0; s--) + *s = xdigs[(unsigned int)*s]; + + return (s0); +} + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + +/* + * This is the long double version of __hdtoa(). + */ +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + static const int sigfigs = (LDBL_MANT_DIG + 3) / 4; + struct ieee_ext *p = (struct ieee_ext *)&e; + char *s, *s0; + int bufsize; + + *sign = p->ext_sign; + + switch (fpclassify(e)) { + case FP_NORMAL: + *decpt = p->ext_exp - LDBL_ADJ; + break; + case FP_ZERO: + *decpt = 1; + return (nrv_alloc("0", rve, 1)); + case FP_SUBNORMAL: + e *= 0x1p514L; + *decpt = p->ext_exp - (514 + LDBL_ADJ); + break; + case FP_INFINITE: + *decpt = INT_MAX; + return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1)); + case FP_NAN: + *decpt = INT_MAX; + return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1)); + default: + abort(); + } + + /* FP_NORMAL or FP_SUBNORMAL */ + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * For simplicity, we generate all the digits even if the + * caller has requested fewer. + */ + bufsize = (sigfigs > ndigits) ? sigfigs : ndigits; + s0 = rv_alloc(bufsize); + + /* + * We work from right to left, first adding any requested zero + * padding, then the least significant portion of the + * mantissa, followed by the most significant. The buffer is + * filled with the byte values 0x0 through 0xf, which are + * converted to xdigs[0x0] through xdigs[0xf] after the + * rounding phase. + */ + for (s = s0 + bufsize - 1; s > s0 + sigfigs - 1; s--) + *s = 0; + for (; s > s0 + sigfigs - (EXT_FRACLBITS / 4) - 1 && s > s0; s--) { + *s = p->ext_fracl & 0xf; + p->ext_fracl >>= 4; + } +#ifdef EXT_FRACHMBITS + for (; s > s0; s--) { + *s = p->ext_frachm & 0xf; + p->ext_frachm >>= 4; + } +#endif +#ifdef EXT_FRACLMBITS + for (; s > s0; s--) { + *s = p->ext_fraclm & 0xf; + p->ext_fraclm >>= 4; + } +#endif + for (; s > s0; s--) { + *s = p->ext_frach & 0xf; + p->ext_frach >>= 4; + } + + /* + * At this point, we have snarfed all the bits in the + * mantissa, with the possible exception of the highest-order + * (partial) nibble, which is dealt with by the next + * statement. We also tack on the implicit normalization bit. + */ + *s = p->ext_frach | (1U << ((LDBL_MANT_DIG - 1) % 4)); + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = sigfigs; s0[ndigits - 1] == 0; ndigits--) + ; + } + + if (sigfigs > ndigits && s0[ndigits] != 0) + dorounding(s0, ndigits, p->ext_sign, decpt); + + s = s0 + ndigits; + if (rve != NULL) + *rve = s; + *s-- = '\0'; + for (; s >= s0; s--) + *s = xdigs[(unsigned int)*s]; + + return (s0); +} + +#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +char * +__hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, + char **rve) +{ + return (__hdtoa((double)e, xdigs, ndigits, decpt, sign, rve)); +} + +#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ diff --git a/lib/libc/gdtoa/hexnan.c b/lib/libc/gdtoa/hexnan.c new file mode 100644 index 00000000000..e07e069ad69 --- /dev/null +++ b/lib/libc/gdtoa/hexnan.c @@ -0,0 +1,150 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2000 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + static void +#ifdef KR_headers +L_shift(x, x1, i) ULong *x; ULong *x1; int i; +#else +L_shift(ULong *x, ULong *x1, int i) +#endif +{ + int j; + + i = 8 - i; + i <<= 2; + j = ULbits - i; + do { + *x |= x[1] << j; + x[1] >>= i; + } while(++x < x1); + } + + int +#ifdef KR_headers +hexnan(sp, fpi, x0) + CONST char **sp; FPI *fpi; ULong *x0; +#else +hexnan( CONST char **sp, FPI *fpi, ULong *x0) +#endif +{ + ULong c, h, *x, *x1, *xe; + CONST char *s; + int havedig, hd0, i, nbits; + + if (!hexdig['0']) + hexdig_init_D2A(); + nbits = fpi->nbits; + x = x0 + (nbits >> kshift); + if (nbits & kmask) + x++; + *--x = 0; + x1 = xe = x; + havedig = hd0 = i = 0; + s = *sp; + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + while(c = *(CONST unsigned char*)++s) { + if (!(h = hexdig[c])) { + if (c <= ' ') { + if (hd0 < havedig) { + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x <= x0) { + i = 8; + continue; + } + hd0 = havedig; + *--x = 0; + x1 = x; + i = 0; + } + while(*(CONST unsigned char*)(s+1) <= ' ') + ++s; + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X') + && *(CONST unsigned char*)(s+3) > ' ') + s += 2; + continue; + } + if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } +#ifndef GDTOA_NON_PEDANTIC_NANCHECK + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while(c = *++s); +#endif + return STRTOG_NaN; + } + havedig++; + if (++i > 8) { + if (x <= x0) + continue; + i = 1; + *--x = 0; + } + *x = (*x << 4) | h & 0xf; + } + if (!havedig) + return STRTOG_NaN; + if (x < x1 && i < 8) + L_shift(x, x1, i); + if (x > x0) { + x1 = x0; + do *x1++ = *x++; + while(x <= xe); + do *x1++ = 0; + while(x1 <= xe); + } + else { + /* truncate high-order word if necessary */ + if ( (i = nbits & (ULbits-1)) !=0) + *xe &= ((ULong)0xffffffff) >> (ULbits - i); + } + for(x1 = xe;; --x1) { + if (*x1 != 0) + break; + if (x1 == x0) { + *x1 = 1; + break; + } + } + return STRTOG_NaNbits; + } diff --git a/lib/libc/gdtoa/ldtoa.c b/lib/libc/gdtoa/ldtoa.c new file mode 100644 index 00000000000..793d71cffb5 --- /dev/null +++ b/lib/libc/gdtoa/ldtoa.c @@ -0,0 +1,124 @@ +/* $OpenBSD: ldtoa.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#ifndef __vax__ +#include <machine/ieee.h> +#endif /* !__vax__ */ +#include <float.h> +#include <inttypes.h> +#include <limits.h> +#include <math.h> +#include <stdlib.h> +#include "gdtoaimp.h" + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + +/* + * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(), + * except that the floating point argument is passed by reference. + * When dtoa() is passed a NaN or infinity, it sets expt to 9999. + * However, a long double could have a valid exponent of 9999, so we + * use INT_MAX in ldtoa() instead. + */ +char * +__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) +{ + FPI fpi = { + LDBL_MANT_DIG, /* nbits */ + LDBL_MIN_EXP - LDBL_MANT_DIG, /* emin */ + LDBL_MAX_EXP - LDBL_MANT_DIG, /* emax */ + FLT_ROUNDS, /* rounding */ +#ifdef Sudden_Underflow /* unused, but correct anyway */ + 1 +#else + 0 +#endif + }; + int be, kind; + char *ret; + struct ieee_ext *p = (struct ieee_ext *)ld; + uint32_t bits[(LDBL_MANT_DIG + 31) / 32]; + void *vbits = bits; + + /* + * gdtoa doesn't know anything about the sign of the number, so + * if the number is negative, we need to swap rounding modes of + * 2 (upwards) and 3 (downwards). + */ + *sign = p->ext_sign; + fpi.rounding ^= (fpi.rounding >> 1) & p->ext_sign; + + be = p->ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1); + EXT_TO_ARRAY32(p, bits); + + switch (fpclassify(*ld)) { + case FP_NORMAL: + kind = STRTOG_Normal; +#ifdef EXT_IMPLICIT_NBIT + bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32); +#endif /* EXT_IMPLICIT_NBIT */ + break; + case FP_ZERO: + kind = STRTOG_Zero; + break; + case FP_SUBNORMAL: + kind = STRTOG_Denormal; + be++; + break; + case FP_INFINITE: + kind = STRTOG_Infinite; + break; + case FP_NAN: + kind = STRTOG_NaN; + break; + default: + abort(); + } + + ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve); + if (*decpt == -32768) + *decpt = INT_MAX; + return ret; +} + +#else /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ + +char * +__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign, + char **rve) +{ + char *ret; + + ret = dtoa((double)*ld, mode, ndigits, decpt, sign, rve); + if (*decpt == 9999) + *decpt = INT_MAX; + return ret; +} + +#endif /* (LDBL_MANT_DIG == DBL_MANT_DIG) */ diff --git a/lib/libc/gdtoa/locks.c b/lib/libc/gdtoa/locks.c new file mode 100644 index 00000000000..75df2cb750d --- /dev/null +++ b/lib/libc/gdtoa/locks.c @@ -0,0 +1,7 @@ +/* $OpenBSD: locks.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ + +/* Written by Martynas Venckus. Public Domain. */ + +#include <stdio.h> + +void *__dtoa_locks[] = { NULL, NULL }; diff --git a/lib/libc/gdtoa/misc.c b/lib/libc/gdtoa/misc.c new file mode 100644 index 00000000000..b3ce7c9b8a4 --- /dev/null +++ b/lib/libc/gdtoa/misc.c @@ -0,0 +1,865 @@ +/**************************************************************** + +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 *freelist[Kmax+1]; +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + + Bigint * +Balloc +#ifdef KR_headers + (k) int k; +#else + (int k) +#endif +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + unsigned int len; +#endif + + ACQUIRE_DTOA_LOCK(0); + if ( (rv = freelist[k]) !=0) { + freelist[k] = rv->next; + } + else { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; + } + + void +Bfree +#ifdef KR_headers + (v) Bigint *v; +#else + (Bigint *v) +#endif +{ + if (v) { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } + + int +lo0bits +#ifdef KR_headers + (y) ULong *y; +#else + (ULong *y) +#endif +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; + } + + Bigint * +multadd +#ifdef KR_headers + (b, m, a) Bigint *b; int m, a; +#else + (Bigint *b, int m, int a) /* multiply by m and add a */ +#endif +{ + int i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & 0xffffffffUL; +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; + } + + int +hi0bits_D2A +#ifdef KR_headers + (x) register ULong x; +#else + (register ULong x) +#endif +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; + } + + Bigint * +i2b +#ifdef KR_headers + (i) int i; +#else + (int i) +#endif +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; + } + + Bigint * +mult +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & 0xffffffffUL; + } + while(x < xae); + *xc = carry; + } + } +#else +#ifdef Pack_32 + for(; xb < xbe; xb++, xc0++) { + if ( (y = *xb & 0xffff) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ( (y = *xb >> 16) !=0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if ( (y = *xb++) !=0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; + } + + static Bigint *p5s; + + Bigint * +pow5mult +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ( (i = k & 3) !=0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if ((p5 = p5s) == 0) { + /* first time */ +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if ((p51 = p5->next) == 0) { +#ifdef MULTIPLE_THREADS + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; + } + + Bigint * +lshift +#ifdef KR_headers + (b, k) Bigint *b; int k; +#else + (Bigint *b, int k) +#endif +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> kshift; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= kmask) { +#ifdef Pack_32 + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) !=0) + ++n1; +#else + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) + ++n1; +#endif + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; + } + + int +cmp +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; + } + + Bigint * +diff +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = y & 0xffffffffUL; + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; + } + + double +b2d +#ifdef KR_headers + (a, e) Bigint *a; int *e; +#else + (Bigint *a, int *e) +#endif +{ + ULong *xa, *xa0, w, y, z; + int k; + double d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + d1 = y << (32-Ebits) + k | w >> Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> 32 - k; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif + ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#endif + return dval(d); + } +#undef d0 +#undef d1 + + Bigint * +d2b +#ifdef KR_headers + (d, e, bits) double d; int *e, *bits; +#else + (double d, int *e, int *bits) +#endif +{ + Bigint *b; +#ifndef Sudden_Underflow + int i; +#endif + int de, k; + ULong *x, y, z; +#ifdef VAX + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ( (de = (int)(d0 >> Exp_shift)) !=0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) { + x[0] = y | z << 32 - k; + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) !=0 ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if ( (y = d1) !=0) { + if ( (k = lo0bits(&y)) !=0) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; + } +#undef d0 +#undef d1 + + CONST double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 + }; +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#else +bigtens[] = { 1e16, 1e32 }; +CONST double tinytens[] = { 1e-16, 1e-32 }; +#endif +#endif + + CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif + }; + + char * +#ifdef KR_headers +strcp_D2A(a, b) char *a; char *b; +#else +strcp_D2A(char *a, CONST char *b) +#endif +{ + while(*a = *b++) + a++; + return a; + } + +#ifdef NO_STRING_H + + Char * +#ifdef KR_headers +memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; +#else +memcpy_D2A(void *a1, void *b1, size_t len) +#endif +{ + register char *a = (char*)a1, *ae = a + len; + register char *b = (char*)b1, *a0 = a; + while(a < ae) + *a++ = *b++; + return a0; + } + +#endif /* NO_STRING_H */ diff --git a/lib/libc/gdtoa/qnan.c b/lib/libc/gdtoa/qnan.c new file mode 100644 index 00000000000..118e749216a --- /dev/null +++ b/lib/libc/gdtoa/qnan.c @@ -0,0 +1,110 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2005 by David M. Gay +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 +the author or any of his current or former employers not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS 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 "."). */ + +/* Program to compute quiet NaNs of various precisions (float, */ +/* double, and perhaps long double) on the current system, */ +/* provided the system uses binary IEEE (P754) arithmetic. */ +/* Note that one system's quiet NaN may be a signaling NaN on */ +/* another system. The IEEE arithmetic standards (P754, P854) */ +/* do not specify how to distinguish signaling NaNs from quiet */ +/* ones, and this detail varies across systems. The computed */ +/* NaN values are encoded in #defines for values for an */ +/* unsigned 32-bit integer type, called Ulong below, and */ +/* (for long double) perhaps as unsigned short values. Once */ +/* upon a time, there were PC compilers for Intel CPUs that */ +/* had sizeof(long double) = 10. Are such compilers still */ +/* distributed? */ + +#include <stdio.h> +#include "arith.h" + +#ifndef Long +#define Long long +#endif + +typedef unsigned Long Ulong; + +#undef HAVE_IEEE +#ifdef IEEE_8087 +#define _0 1 +#define _1 0 +#define HAVE_IEEE +#endif +#ifdef IEEE_MC68k +#define _0 0 +#define _1 1 +#define HAVE_IEEE +#endif + +#define UL (unsigned long) + + int +main(void) +{ +#ifdef HAVE_IEEE + typedef union { + float f; + double d; + Ulong L[4]; +#ifndef NO_LONG_LONG + unsigned short u[5]; + long double D; +#endif + } U; + U a, b, c; + int i; + + a.L[0] = b.L[0] = 0x7f800000; + c.f = a.f - b.f; + printf("#define f_QNAN 0x%lx\n", UL c.L[0]); + a.L[_0] = b.L[_0] = 0x7ff00000; + a.L[_1] = b.L[_1] = 0; + c.d = a.d - b.d; /* quiet NaN */ + printf("#define d_QNAN0 0x%lx\n", UL c.L[0]); + printf("#define d_QNAN1 0x%lx\n", UL c.L[1]); +#ifdef NO_LONG_LONG + for(i = 0; i < 4; i++) + printf("#define ld_QNAN%d 0xffffffff\n", i); + for(i = 0; i < 5; i++) + printf("#define ldus_QNAN%d 0xffff\n", i); +#else + b.D = c.D = a.d; + if (printf("") < 0) + c.D = 37; /* never executed; just defeat optimization */ + a.L[2] = a.L[3] = 0; + a.D = b.D - c.D; + for(i = 0; i < 4; i++) + printf("#define ld_QNAN%d 0x%lx\n", i, UL a.L[i]); + for(i = 0; i < 5; i++) + printf("#define ldus_QNAN%d 0x%x\n", i, a.u[i]); +#endif +#endif /* HAVE_IEEE */ + return 0; + } diff --git a/lib/libc/gdtoa/smisc.c b/lib/libc/gdtoa/smisc.c new file mode 100644 index 00000000000..163011e0aa2 --- /dev/null +++ b/lib/libc/gdtoa/smisc.c @@ -0,0 +1,191 @@ +/**************************************************************** + +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" + + Bigint * +s2b +#ifdef KR_headers + (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +#else + (CONST char *s, int nd0, int nd, ULong y9) +#endif +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do b = multadd(b, 10, *s++ - '0'); + while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; + } + + double +ratio +#ifdef KR_headers + (a, b) Bigint *a, *b; +#else + (Bigint *a, Bigint *b) +#endif +{ + double da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); + k = ka - kb + ULbits*(a->wds - b->wds); +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); + } + +#ifdef INFNAN_CHECK + + int +match +#ifdef KR_headers + (sp, t) char **sp, *t; +#else + (CONST char **sp, char *t) +#endif +{ + int c, d; + CONST char *s = *sp; + + while( (d = *t++) !=0) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } +#endif /* INFNAN_CHECK */ + + void +#ifdef KR_headers +copybits(c, n, b) ULong *c; int n; Bigint *b; +#else +copybits(ULong *c, int n, Bigint *b) +#endif +{ + ULong *ce, *x, *xe; +#ifdef Pack_16 + int nw, nw1; +#endif + + ce = c + ((n-1) >> kshift) + 1; + x = b->x; +#ifdef Pack_32 + xe = x + b->wds; + while(x < xe) + *c++ = *x++; +#else + nw = b->wds; + nw1 = nw & 1; + for(xe = x + (nw - nw1); x < xe; x += 2) + Storeinc(c, x[1], x[0]); + if (nw1) + *c++ = *x; +#endif + while(c < ce) + *c++ = 0; + } + + ULong +#ifdef KR_headers +any_on(b, k) Bigint *b; int k; +#else +any_on(Bigint *b, int k) +#endif +{ + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) + n = nwds; + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) + return 1; + } + x0 = x; + x += n; + while(x > x0) + if (*--x) + return 1; + return 0; + } diff --git a/lib/libc/gdtoa/strtoIQ.c b/lib/libc/gdtoa/strtoIQ.c new file mode 100644 index 00000000000..9ce5120e6b7 --- /dev/null +++ b/lib/libc/gdtoa/strtoIQ.c @@ -0,0 +1,63 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtoIQ(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIQ(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoQ(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoQ(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtoId.c b/lib/libc/gdtoa/strtoId.c new file mode 100644 index 00000000000..1c97d382dea --- /dev/null +++ b/lib/libc/gdtoa/strtoId.c @@ -0,0 +1,60 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtoId(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoId(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtod((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtod((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtoIdd.c b/lib/libc/gdtoa/strtoIdd.c new file mode 100644 index 00000000000..40b7936bc00 --- /dev/null +++ b/lib/libc/gdtoa/strtoIdd.c @@ -0,0 +1,66 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIdd(s, sp, f0, f1) CONST char *s; char **sp; double *f0, *f1; +#else +strtoIdd(CONST char *s, char **sp, double *f0, double *f1) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(2); + B[0]->wds = 4; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtodd((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtodd((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + ((ULong*)f1)[0] = ((ULong*)f0)[0]; + ((ULong*)f1)[1] = ((ULong*)f0)[1]; + ((ULong*)f1)[2] = ((ULong*)f0)[2]; + ((ULong*)f1)[3] = ((ULong*)f0)[3]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtoIf.c b/lib/libc/gdtoa/strtoIf.c new file mode 100644 index 00000000000..65ecab2e0b8 --- /dev/null +++ b/lib/libc/gdtoa/strtoIf.c @@ -0,0 +1,58 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtoIf(s, sp, f0, f1) CONST char *s; char **sp; float *f0, *f1; +#else +strtoIf(CONST char *s, char **sp, float *f0, float *f1) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + + B[0] = Balloc(0); + B[0]->wds = 1; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtof((ULong*)f0, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtof((ULong*)f1, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else + *(ULong*)f1 = *(ULong*)f0; + return k; + } diff --git a/lib/libc/gdtoa/strtoIg.c b/lib/libc/gdtoa/strtoIg.c new file mode 100644 index 00000000000..ec46a3ebb75 --- /dev/null +++ b/lib/libc/gdtoa/strtoIg.c @@ -0,0 +1,133 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtoIg(s00, se, fpi, exp, B, rvp) CONST char *s00; char **se; FPI *fpi; Long *exp; Bigint **B; int *rvp; +#else +strtoIg(CONST char *s00, char **se, FPI *fpi, Long *exp, Bigint **B, int *rvp) +#endif +{ + Bigint *b, *b1; + int i, nb, nw, nw1, rv, rv1, swap; + unsigned int nb1, nb11; + Long e1; + + b = *B; + rv = strtodg(s00, se, fpi, exp, b->x); + if (!(rv & STRTOG_Inexact)) { + B[1] = 0; + return *rvp = rv; + } + e1 = exp[0]; + rv1 = rv ^ STRTOG_Inexact; + b1 = Balloc(b->k); + Bcopy(b1, b); + nb = fpi->nbits; + nb1 = nb & 31; + nb11 = (nb1 - 1) & 31; + nw = b->wds; + nw1 = nw - 1; + if (rv & STRTOG_Inexlo) { + swap = 0; + b1 = increment(b1); + if (fpi->sudden_underflow + && (rv & STRTOG_Retmask) == STRTOG_Zero) { + b1->x[0] = 0; + b1->x[nw1] = 1L << nb11; + rv1 += STRTOG_Normal - STRTOG_Zero; + rv1 &= ~STRTOG_Underflow; + goto swapcheck; + } + if (b1->wds > nw + || nb1 && b1->x[nw1] & 1L << nb1) { + if (++e1 > fpi->emax) + rv1 = STRTOG_Infinite | STRTOG_Inexhi; + rshift(b1, 1); + } + else if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + if (b1->x[nw1] & 1L << nb11) { + rv1 += STRTOG_Normal - STRTOG_Denormal; + rv1 &= ~STRTOG_Underflow; + } + } + } + else { + swap = STRTOG_Neg; + if ((rv & STRTOG_Retmask) == STRTOG_Infinite) { + b1 = set_ones(b1, nb); + e1 = fpi->emax; + rv1 = STRTOG_Normal | STRTOG_Inexlo; + goto swapcheck; + } + decrement(b1); + if ((rv & STRTOG_Retmask) == STRTOG_Denormal) { + for(i = nw1; !b1->x[i]; --i) + if (!i) { + rv1 = STRTOG_Zero | STRTOG_Inexlo; + break; + } + goto swapcheck; + } + if (!(b1->x[nw1] & 1L << nb11)) { + if (e1 == fpi->emin) { + if (fpi->sudden_underflow) + rv1 += STRTOG_Zero - STRTOG_Normal; + else + rv1 += STRTOG_Denormal - STRTOG_Normal; + rv1 |= STRTOG_Underflow; + } + else { + b1 = lshift(b1, 1); + b1->x[0] |= 1; + --e1; + } + } + } + swapcheck: + if (swap ^ (rv & STRTOG_Neg)) { + rvp[0] = rv1; + rvp[1] = rv; + B[0] = b1; + B[1] = b; + exp[1] = exp[0]; + exp[0] = e1; + } + else { + rvp[0] = rv; + rvp[1] = rv1; + B[1] = b1; + exp[1] = e1; + } + return rv; + } diff --git a/lib/libc/gdtoa/strtoIx.c b/lib/libc/gdtoa/strtoIx.c new file mode 100644 index 00000000000..783a631f066 --- /dev/null +++ b/lib/libc/gdtoa/strtoIx.c @@ -0,0 +1,64 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + + int +#ifdef KR_headers +strtoIx(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIx(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + UShort *L = (UShort *)a, *M = (UShort *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtox(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtox(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + M[3] = L[3]; + M[4] = L[4]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtoIxL.c b/lib/libc/gdtoa/strtoIxL.c new file mode 100644 index 00000000000..869bfd16fb8 --- /dev/null +++ b/lib/libc/gdtoa/strtoIxL.c @@ -0,0 +1,62 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtoIxL(s, sp, a, b) CONST char *s; char **sp; void *a; void *b; +#else +strtoIxL(CONST char *s, char **sp, void *a, void *b) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + Long exp[2]; + Bigint *B[2]; + int k, rv[2]; + ULong *L = (ULong *)a, *M = (ULong *)b; + + B[0] = Balloc(1); + B[0]->wds = 2; + k = strtoIg(s, sp, &fpi, exp, B, rv); + ULtoxL(L, B[0]->x, exp[0], rv[0]); + Bfree(B[0]); + if (B[1]) { + ULtoxL(M, B[1]->x, exp[1], rv[1]); + Bfree(B[1]); + } + else { + M[0] = L[0]; + M[1] = L[1]; + M[2] = L[2]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtod.c b/lib/libc/gdtoa/strtod.c new file mode 100644 index 00000000000..66a3baa2bc3 --- /dev/null +++ b/lib/libc/gdtoa/strtod.c @@ -0,0 +1,982 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" +#ifndef NO_FENV_H +#include <fenv.h> +#endif + +#ifdef USE_LOCALE +#include "locale.h" +#endif + +#ifdef IEEE_Arith +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#undef tinytens +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, + 9007199254740992.e-256 + }; +#endif +#endif + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + + double +strtod +#ifdef KR_headers + (s00, se) CONST char *s00; char **se; +#else + (CONST char *s00, char **se) +#endif +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif + + sign = nz0 = nz = decpt = 0; + dval(rv) = 0.; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + { + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + Long exp; + ULong bits[2]; + switch(s[1]) { + case 'x': + case 'X': + { +#if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) + FPI fpi1 = fpi; + switch(fegetround()) { + case FE_TOWARDZERO: fpi1.rounding = 0; break; + case FE_UPWARD: fpi1.rounding = 2; break; + case FE_DOWNWARD: fpi1.rounding = 3; + } +#else +#define fpi1 fpi +#endif + switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { + case STRTOG_NoNumber: + s = s00; + sign = 0; + case STRTOG_Zero: + break; + default: + if (bb) { + copybits(bits, fpi.nbits, bb); + Bfree(bb); + } + ULtod(((U*)&rv)->L, bits, exp, i); + }} + goto ret; + } + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + decpt = 1; + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + ULong bits[2]; + static FPI fpinan = /* only 52 explicit bits */ + { 52, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { +#ifndef No_Hex_NaN + if (*s == '(' /*)*/ + && hexnan(&s, &fpinan, bits) + == STRTOG_NaNbits) { + word0(rv) = 0x7ff00000 | bits[1]; + word1(rv) = bits[0]; + } + else { +#endif + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + } +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ + ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << j-32; + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { + undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } + apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) + aadj1 += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) + z = 1; + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif + retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); + } + diff --git a/lib/libc/gdtoa/strtodI.c b/lib/libc/gdtoa/strtodI.c new file mode 100644 index 00000000000..98f889110e0 --- /dev/null +++ b/lib/libc/gdtoa/strtodI.c @@ -0,0 +1,167 @@ +/**************************************************************** + +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" + + static double +#ifdef KR_headers +ulpdown(d) double *d; +#else +ulpdown(double *d) +#endif +{ + double u; + ULong *L = (ULong*)d; + + u = ulp(*d); + if (!(L[_1] | L[_0] & 0xfffff) + && (L[_0] & 0x7ff00000) > 0x00100000) + u *= 0.5; + return u; + } + + int +#ifdef KR_headers +strtodI(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtodI(CONST char *s, char **sp, double *dd) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2], sign; + Long exp; + int j, k; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + k = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + sign = k & STRTOG_Neg ? 0x80000000L : 0; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; +#ifdef Sudden_Underflow + if (k & STRTOG_Inexact) { + if (sign) + u->L[_0] = 0x80100000L; + else + u->L[2+_0] = 0x100000L; + } + break; +#else + goto contain; +#endif + + case STRTOG_Denormal: + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + goto contain; + + case STRTOG_Normal: + u->L[_1] = bits[0]; + u->L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + contain: + j = k & STRTOG_Inexact; + if (sign) { + u->L[_0] |= sign; + j = STRTOG_Inexact - j; + } + switch(j) { + case STRTOG_Inexlo: +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[2+_0] = u->L[_0] + 0x3500000; + u->L[2+_1] = u->L[_1]; + u->d[1] += ulp(u->d[1]); + u->L[2+_0] -= 0x3500000; + if (!(u->L[2+_0] & 0x7ff00000)) { + u->L[2+_0] = sign; + u->L[2+_1] = 0; + } + } + else +#endif + u->d[1] = u->d[0] + ulp(u->d[0]); + break; + case STRTOG_Inexhi: + u->d[1] = u->d[0]; +#ifdef Sudden_Underflow + if ((u->L[_0] & 0x7ff00000) < 0x3500000) { + u->L[_0] += 0x3500000; + u->d[0] -= ulpdown(u->d); + u->L[_0] -= 0x3500000; + if (!(u->L[_0] & 0x7ff00000)) { + u->L[_0] = sign; + u->L[_1] = 0; + } + } + else +#endif + u->d[0] -= ulpdown(u->d); + break; + default: + u->d[1] = u->d[0]; + } + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = sign | 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + if (k & STRTOG_Inexact) { + if (sign) { + u->L[2+_0] = 0xffefffffL; + u->L[2+_1] = 0xffffffffL; + } + else { + u->L[_0] = 0x7fefffffL; + u->L[_1] = 0xffffffffL; + } + } + break; + + case STRTOG_NaN: + u->L[0] = u->L[2] = d_QNAN0; + u->L[1] = u->L[3] = d_QNAN1; + break; + + case STRTOG_NaNbits: + u->L[_0] = u->L[2+_0] = 0x7ff00000 | sign | bits[1]; + u->L[_1] = u->L[2+_1] = bits[0]; + } + return k; + } diff --git a/lib/libc/gdtoa/strtodg.c b/lib/libc/gdtoa/strtodg.c new file mode 100644 index 00000000000..0c008737813 --- /dev/null +++ b/lib/libc/gdtoa/strtodg.c @@ -0,0 +1,1010 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 1998-2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +#include "gdtoaimp.h" + +#ifdef USE_LOCALE +#include "locale.h" +#endif + + static CONST int +fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, + 24, 26, 28, 31, 33, 35, 38, 40, 42, 45, + 47, 49, 52 +#ifdef VAX + , 54, 56 +#endif + }; + + Bigint * +#ifdef KR_headers +increment(b) Bigint *b; +#else +increment(Bigint *b) +#endif +{ + ULong *x, *xe; + Bigint *b1; +#ifdef Pack_16 + ULong carry = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); +#else + do { + y = *x + carry; + carry = y >> 16; + *x++ = y & 0xffff; + if (!carry) + return b; + } while(x < xe); + if (carry) +#endif + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; + } + + int +#ifdef KR_headers +decrement(b) Bigint *b; +#else +decrement(Bigint *b) +#endif +{ + ULong *x, *xe; +#ifdef Pack_16 + ULong borrow = 1, y; +#endif + + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + do { + if (*x) { + --*x; + break; + } + *x++ = 0xffffffffL; + } + while(x < xe); +#else + do { + y = *x - borrow; + borrow = (y & 0x10000) >> 16; + *x++ = y & 0xffff; + } while(borrow && x < xe); +#endif + return STRTOG_Inexlo; + } + + static int +#ifdef KR_headers +all_on(b, n) Bigint *b; int n; +#else +all_on(Bigint *b, int n) +#endif +{ + ULong *x, *xe; + + x = b->x; + xe = x + (n >> kshift); + while(x < xe) + if ((*x++ & ALL_ON) != ALL_ON) + return 0; + if (n &= kmask) + return ((*x | (ALL_ON << n)) & ALL_ON) == ALL_ON; + return 1; + } + + Bigint * +#ifdef KR_headers +set_ones(b, n) Bigint *b; int n; +#else +set_ones(Bigint *b, int n) +#endif +{ + int k; + ULong *x, *xe; + + k = (n + ((1 << kshift) - 1)) >> kshift; + if (b->k < k) { + Bfree(b); + b = Balloc(k); + } + k = n >> kshift; + if (n &= kmask) + k++; + b->wds = k; + x = b->x; + xe = x + k; + while(x < xe) + *x++ = ALL_ON; + if (n) + x[-1] >>= ULbits - n; + return b; + } + + static int +rvOK +#ifdef KR_headers + (d, fpi, exp, bits, exact, rd, irv) + double d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv; +#else + (double d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv) +#endif +{ + Bigint *b; + ULong carry, inex, lostbits; + int bdif, e, j, k, k1, nb, rv; + + carry = rv = 0; + b = d2b(d, &e, &bdif); + bdif -= nb = fpi->nbits; + e += bdif; + if (bdif <= 0) { + if (exact) + goto trunc; + goto ret; + } + if (P == nb) { + if ( +#ifndef IMPRECISE_INEXACT + exact && +#endif + fpi->rounding == +#ifdef RND_PRODQUOT + FPI_Round_near +#else + Flt_Rounds +#endif + ) goto trunc; + goto ret; + } + switch(rd) { + case 1: + goto trunc; + case 2: + break; + default: /* round near */ + k = bdif - 1; + if (k < 0) + goto trunc; + if (!k) { + if (!exact) + goto ret; + if (b->x[0] & 2) + break; + goto trunc; + } + if (b->x[k>>kshift] & ((ULong)1 << (k & kmask))) + break; + goto trunc; + } + /* "break" cases: round up 1 bit, then truncate; bdif > 0 */ + carry = 1; + trunc: + inex = lostbits = 0; + if (bdif > 0) { + if ( (lostbits = any_on(b, bdif)) !=0) + inex = STRTOG_Inexlo; + rshift(b, bdif); + if (carry) { + inex = STRTOG_Inexhi; + b = increment(b); + if ( (j = nb & kmask) !=0) + j = ULbits - j; + if (hi0bits(b->x[b->wds - 1]) != j) { + if (!lostbits) + lostbits = b->x[0] & 1; + rshift(b, 1); + e++; + } + } + } + else if (bdif < 0) + b = lshift(b, -bdif); + if (e < fpi->emin) { + k = fpi->emin - e; + e = fpi->emin; + if (k > nb || fpi->sudden_underflow) { + b->wds = inex = 0; + *irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + k1 = k - 1; + if (k1 > 0 && !lostbits) + lostbits = any_on(b, k1); + if (!lostbits && !exact) + goto ret; + lostbits |= + carry = b->x[k1>>kshift] & (1 << (k1 & kmask)); + rshift(b, k); + *irv = STRTOG_Denormal; + if (carry) { + b = increment(b); + inex = STRTOG_Inexhi | STRTOG_Underflow; + } + else if (lostbits) + inex = STRTOG_Inexlo | STRTOG_Underflow; + } + } + else if (e > fpi->emax) { + e = fpi->emax + 1; + *irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + b->wds = inex = 0; + } + *exp = e; + copybits(bits, nb, b); + *irv |= inex; + rv = 1; + ret: + Bfree(b); + return rv; + } + + static int +#ifdef KR_headers +mantbits(d) double d; +#else +mantbits(double d) +#endif +{ + ULong L; +#ifdef VAX + L = word1(d) << 16 | word1(d) >> 16; + if (L) +#else + if ( (L = word1(d)) !=0) +#endif + return P - lo0bits(&L); +#ifdef VAX + L = word0(d) << 16 | word0(d) >> 16 | Exp_msk11; +#else + L = word0(d) | Exp_msk1; +#endif + return P - 32 - lo0bits(&L); + } + + int +strtodg +#ifdef KR_headers + (s00, se, fpi, exp, bits) + CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; +#else + (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits) +#endif +{ + int abe, abits, asub; + int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; + int dsign, e, e1, e2, emin, esign, finished, i, inex, irv; + int j, k, nbits, nd, nd0, nf, nz, nz0, rd, rvbits, rve, rve1, sign; + int sudden_underflow; + CONST char *s, *s0, *s1; + double adj, adj0, rv, tol; + Long L; + ULong y, z; + Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; + + irv = STRTOG_Zero; + denorm = sign = nz0 = nz = 0; + dval(rv) = 0.; + rvb = 0; + nbits = fpi->nbits; + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + sign = 0; + irv = STRTOG_NoNumber; + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } + break2: + if (*s == '0') { +#ifndef NO_HEX_FP + switch(s[1]) { + case 'x': + case 'X': + irv = gethex(&s, fpi, exp, &rvb, sign); + if (irv == STRTOG_NoNumber) { + s = s00; + sign = 0; + } + goto ret; + } +#endif + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + sudden_underflow = fpi->sudden_underflow; + s0 = s; + y = z = 0; + for(decpt = nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + if (c == *localeconv()->decimal_point) +#else + if (c == '.') +#endif + { + decpt = 1; + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } + dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + irv = STRTOG_NoNumber; + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + if (!decpt) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + irv = STRTOG_Infinite; + goto infnanexp; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + irv = STRTOG_NaN; + *exp = fpi->emax + 1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + irv = hexnan(&s, fpi, bits); +#endif + goto infnanexp; + } + } +#endif /* INFNAN_CHECK */ + irv = STRTOG_NoNumber; + s = s00; + } + goto ret; + } + + irv = STRTOG_Normal; + e1 = e -= nf; + rd = 0; + switch(fpi->rounding & 3) { + case FPI_Round_up: + rd = 2 - sign; + break; + case FPI_Round_zero: + rd = 1; + break; + case FPI_Round_down: + rd = 1 + sign; + } + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) + dval(rv) = tens[k - 9] * dval(rv) + z; + bd0 = 0; + if (nbits <= P && nd <= DBL_DIG) { + if (!e) { + if (rvOK(dval(rv), fpi, exp, bits, 1, rd, &irv)) + goto ret; + } + else if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else + i = fivesbits[e] + mantbits(dval(rv)) <= P; + /* rv = */ rounded_product(dval(rv), tens[e]); + if (rvOK(dval(rv), fpi, exp, bits, i, rd, &irv)) + goto ret; + e1 -= e; + goto rv_notOK; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e2 = e - i; + e1 -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ + vax_ovfl_check: + dval(adj) = dval(rv); + word0(adj) -= P*Exp_msk1; + /* adj = */ rounded_product(dval(adj), tens[e2]); + if ((word0(adj) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto rv_notOK; + word0(adj) += P*Exp_msk1; + dval(rv) = dval(adj); +#else + /* rv = */ rounded_product(dval(rv), tens[e2]); +#endif + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e2; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + if (rvOK(dval(rv), fpi, exp, bits, 0, rd, &irv)) + goto ret; + e1 -= e; + } +#endif + } + rv_notOK: + e1 += nd - k; + + /* Get starting approximation = rv * 10**e1 */ + + e2 = 0; + if (e1 > 0) { + if ( (i = e1 & 15) !=0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= bigtens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + } + } + else if (e1 < 0) { + e1 = -e1; + if ( (i = e1 & 15) !=0) + dval(rv) /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + while(e1 >= (1 << n_bigtens-1)) { + e2 += ((word0(rv) & Exp_mask) + >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + dval(rv) *= tinytens[n_bigtens-1]; + e1 -= 1 << n_bigtens-1; + } + e2 += ((word0(rv) & Exp_mask) >> Exp_shift1) - Bias; + word0(rv) &= ~Exp_mask; + word0(rv) |= Bias << Exp_shift1; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + } + } +#ifdef IBM + /* e2 is a correction to the (base 2) exponent of the return + * value, reflecting adjustments above to avoid overflow in the + * native arithmetic. For native IBM (base 16) arithmetic, we + * must multiply e2 by 4 to change from base 16 to 2. + */ + e2 <<= 2; +#endif + rvb = d2b(dval(rv), &rve, &rvbits); /* rv = rvb * 2^rve */ + rve += e2; + if ((j = rvbits - nbits) > 0) { + rshift(rvb, j); + rvbits = nbits; + rve += j; + } + bb0 = 0; /* trailing zero bits in rvb */ + e2 = rve + rvbits - nbits; + if (e2 > fpi->emax + 1) + goto huge; + rve1 = rve + rvbits - nbits; + if (e2 < (emin = fpi->emin)) { + denorm = 1; + j = rve - emin; + if (j > 0) { + rvb = lshift(rvb, j); + rvbits += j; + } + else if (j < 0) { + rvbits += j; + if (rvbits <= 0) { + if (rvbits < -1) { + ufl: + rvb->wds = 0; + rvb->x[0] = 0; + *exp = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + goto ret; + } + rvb->x[0] = rvb->wds = rvbits = 1; + } + else + rshift(rvb, -j); + } + rve = rve1 = emin; + if (sudden_underflow && e2 + 1 < emin) + goto ufl; + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = Balloc(rvb->k); + Bcopy(bb, rvb); + bbbits = rvbits - bb0; + bbe = rve + bb0; + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; + j = nbits + 1 - bbbits; + i = bbe + bbbits - nbits; + if (i < emin) /* denormal */ + j += i - emin; + bb2 += j; + bd2 += j; + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + bb2 -= bb0; + if (bb2 > 0) + bb = lshift(bb, bb2); + else if (bb2 < 0) + rshift(bb, -bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + asub = 1; + inex = STRTOG_Inexhi; + delta = diff(bb, bd); + if (delta->wds <= 1 && !delta->x[0]) + break; + dsign = delta->sign; + delta->sign = finished = 0; + L = 0; + i = cmp(delta, bs); + if (rd && i <= 0) { + irv = STRTOG_Normal; + if ( (finished = dsign ^ (rd&1)) !=0) { + if (dsign != 0) { + irv |= STRTOG_Inexhi; + goto adj1; + } + irv |= STRTOG_Inexlo; + if (rve1 == emin) + goto adj1; + for(i = 0, j = nbits; j >= ULbits; + i++, j -= ULbits) { + if (rvb->x[i] & ALL_ON) + goto adj1; + } + if (j > 1 && lo0bits(rvb->x + i) < j - 1) + goto adj1; + rve = rve1 - 1; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + irv |= dsign ? STRTOG_Inexlo : STRTOG_Inexhi; + break; + } + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + irv = dsign + ? STRTOG_Normal | STRTOG_Inexlo + : STRTOG_Normal | STRTOG_Inexhi; + if (dsign || bbbits > 1 || denorm || rve1 == emin) + break; + delta = lshift(delta,1); + if (cmp(delta, bs) > 0) { + irv = STRTOG_Normal | STRTOG_Inexlo; + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if (denorm && all_on(rvb, rvbits)) { + /*boundary case -- increment exponent*/ + rvb->wds = 1; + rvb->x[0] = 1; + rve = emin + nbits - (rvbits = 1); + irv = STRTOG_Normal | STRTOG_Inexhi; + denorm = 0; + break; + } + irv = STRTOG_Normal | STRTOG_Inexlo; + } + else if (bbbits == 1) { + irv = STRTOG_Normal; + drop_down: + /* boundary case -- decrement exponent */ + if (rve1 == emin) { + irv = STRTOG_Normal | STRTOG_Inexhi; + if (rvb->wds == 1 && rvb->x[0] == 1) + sudden_underflow = 1; + break; + } + rve -= nbits; + rvb = set_ones(rvb, rvbits = nbits); + break; + } + else + irv = STRTOG_Normal | STRTOG_Inexhi; + if (bbbits < nbits && !denorm || !(rvb->x[0] & 1)) + break; + if (dsign) { + rvb = increment(rvb); + j = kmask & (ULbits - (rvbits & kmask)); + if (hi0bits(rvb->x[rvb->wds - 1]) != j) + rvbits++; + irv = STRTOG_Normal | STRTOG_Inexhi; + } + else { + if (bbbits == 1) + goto undfl; + decrement(rvb); + irv = STRTOG_Normal | STRTOG_Inexlo; + } + break; + } + if ((dval(adj) = ratio(delta, bs)) <= 2.) { + adj1: + inex = STRTOG_Inexlo; + if (dsign) { + asub = 0; + inex = STRTOG_Inexhi; + } + else if (denorm && bbbits <= 1) { + undfl: + rvb->wds = 0; + rve = emin; + irv = STRTOG_Underflow | STRTOG_Inexlo; + break; + } + adj0 = dval(adj) = 1.; + } + else { + adj0 = dval(adj) *= 0.5; + if (dsign) { + asub = 0; + inex = STRTOG_Inexlo; + } + if (dval(adj) < 2147483647.) { + L = adj0; + adj0 -= L; + switch(rd) { + case 0: + if (adj0 >= .5) + goto inc_L; + break; + case 1: + if (asub && adj0 > 0.) + goto inc_L; + break; + case 2: + if (!asub && adj0 > 0.) { + inc_L: + L++; + inex = STRTOG_Inexact - inex; + } + } + dval(adj) = L; + } + } + y = rve + rvbits; + + /* adj *= ulp(dval(rv)); */ + /* if (asub) rv -= adj; else rv += adj; */ + + if (!denorm && rvbits < nbits) { + rvb = lshift(rvb, j = nbits - rvbits); + rve -= j; + rvbits = nbits; + } + ab = d2b(dval(adj), &abe, &abits); + if (abe < 0) + rshift(ab, -abe); + else if (abe > 0) + ab = lshift(ab, abe); + rvb0 = rvb; + if (asub) { + /* rv -= adj; */ + j = hi0bits(rvb->x[rvb->wds-1]); + rvb = diff(rvb, ab); + k = rvb0->wds - 1; + if (denorm) + /* do nothing */; + else if (rvb->wds <= k + || hi0bits( rvb->x[k]) > + hi0bits(rvb0->x[k])) { + /* unlikely; can only have lost 1 high bit */ + if (rve1 == emin) { + --rvbits; + denorm = 1; + } + else { + rvb = lshift(rvb, 1); + --rve; + --rve1; + L = finished = 0; + } + } + } + else { + rvb = sum(rvb, ab); + k = rvb->wds - 1; + if (k >= rvb0->wds + || hi0bits(rvb->x[k]) < hi0bits(rvb0->x[k])) { + if (denorm) { + if (++rvbits == nbits) + denorm = 0; + } + else { + rshift(rvb, 1); + rve++; + rve1++; + L = 0; + } + } + } + Bfree(ab); + Bfree(rvb0); + if (finished) + break; + + z = rve + rvbits; + if (y == z && L) { + /* Can we stop now? */ + tol = dval(adj) * 5e-16; /* > max rel error */ + dval(adj) = adj0 - .5; + if (dval(adj) < -tol) { + if (adj0 > tol) { + irv |= inex; + break; + } + } + else if (dval(adj) > tol && adj0 < 1. - tol) { + irv |= inex; + break; + } + } + bb0 = denorm ? 0 : trailz(rvb); + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } + if (!denorm && (j = nbits - rvbits)) { + if (j > 0) + rvb = lshift(rvb, j); + else + rshift(rvb, -j); + rve -= j; + } + *exp = rve; + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + if (rve > fpi->emax) { + huge: + rvb->wds = 0; + irv = STRTOG_Infinite | STRTOG_Overflow | STRTOG_Inexhi; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + infnanexp: + *exp = fpi->emax + 1; + } + ret: + if (denorm) { + if (sudden_underflow) { + rvb->wds = 0; + irv = STRTOG_Underflow | STRTOG_Inexlo; + } + else { + irv = (irv & ~STRTOG_Retmask) | + (rvb->wds > 0 ? STRTOG_Denormal : STRTOG_Zero); + if (irv & STRTOG_Inexact) + irv |= STRTOG_Underflow; + } + } + if (se) + *se = (char *)s; + if (sign) + irv |= STRTOG_Neg; + if (rvb) { + copybits(bits, nbits, rvb); + Bfree(rvb); + } + return irv; + } diff --git a/lib/libc/gdtoa/strtodnrp.c b/lib/libc/gdtoa/strtodnrp.c new file mode 100644 index 00000000000..19a769f0b43 --- /dev/null +++ b/lib/libc/gdtoa/strtodnrp.c @@ -0,0 +1,87 @@ +/**************************************************************** + +The author of this software is David M. Gay. + +Copyright (C) 2004 by David M. Gay. +All Rights Reserved +Based on material in the rest of /netlib/fp/gdota.tar.gz, +which is copyright (C) 1998, 2000 by Lucent Technologies. + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +****************************************************************/ + +/* This is a variant of strtod that works on Intel ia32 systems */ +/* with the default extended-precision arithmetic -- it does not */ +/* require setting the precision control to 53 bits. */ + +/* 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 +#ifdef KR_headers +strtod(s, sp) CONST char *s; char **sp; +#else +strtod(CONST char *s, char **sp) +#endif +{ + static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + union { ULong L[2]; double d; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = u.L[1] = 0; + break; + + case STRTOG_Normal: + u.L[_1] = bits[0]; + u.L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Denormal: + u.L[_1] = bits[0]; + u.L[_0] = bits[1]; + break; + + case STRTOG_Infinite: + u.L[_0] = 0x7ff00000; + u.L[_1] = 0; + break; + + case STRTOG_NaN: + u.L[0] = d_QNAN0; + u.L[1] = d_QNAN1; + break; + + case STRTOG_NaNbits: + u.L[_0] = 0x7ff00000 | bits[1]; + u.L[_1] = bits[0]; + } + if (k & STRTOG_Neg) + u.L[_0] |= 0x80000000L; + return u.d; + } diff --git a/lib/libc/gdtoa/strtof.c b/lib/libc/gdtoa/strtof.c new file mode 100644 index 00000000000..21bc6c15bfe --- /dev/null +++ b/lib/libc/gdtoa/strtof.c @@ -0,0 +1,73 @@ +/**************************************************************** + +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" + + float +#ifdef KR_headers +strtof(s, sp) CONST char *s; char **sp; +#else +strtof(CONST char *s, char **sp) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1]; + Long exp; + int k; + union { ULong L[1]; float f; } u; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u.L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + u.L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + u.L[0] = bits[0]; + break; + + case STRTOG_Infinite: + u.L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + u.L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + u.L[0] |= 0x80000000L; + return u.f; + } diff --git a/lib/libc/gdtoa/strtold.c b/lib/libc/gdtoa/strtold.c new file mode 100644 index 00000000000..0de6d88c008 --- /dev/null +++ b/lib/libc/gdtoa/strtold.c @@ -0,0 +1,40 @@ +/* $OpenBSD: strtold.c,v 1.1 2008/09/07 20:36:08 martynas Exp $ */ +/*- + * Copyright (c) 2003 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Machine-dependent glue to integrate David Gay's gdtoa + * package into libc for architectures where a long double + * is the same as a double, such as the Alpha. + */ + +#include "gdtoaimp.h" + +long double +strtold(const char * __restrict s, char ** __restrict sp) +{ + return strtod(s, sp); +} diff --git a/lib/libc/gdtoa/strtopQ.c b/lib/libc/gdtoa/strtopQ.c new file mode 100644 index 00000000000..dd5dab826c9 --- /dev/null +++ b/lib/libc/gdtoa/strtopQ.c @@ -0,0 +1,101 @@ +/**************************************************************** + +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 + + int +#ifdef KR_headers +strtopQ(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopQ(CONST char *s, char **sp, void *V) +#endif +{ + static FPI fpi = { 113, 1-16383-113+1, 32766 - 16383 - 113 + 1, 1, SI }; + ULong bits[4]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + L[3] = ld_QNAN3; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/lib/libc/gdtoa/strtopd.c b/lib/libc/gdtoa/strtopd.c new file mode 100644 index 00000000000..42c57fcc1fc --- /dev/null +++ b/lib/libc/gdtoa/strtopd.c @@ -0,0 +1,49 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtopd(s, sp, d) char *s; char **sp; double *d; +#else +strtopd(CONST char *s, char **sp, double *d) +#endif +{ + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + + k = strtodg(s, sp, &fpi0, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtopdd.c b/lib/libc/gdtoa/strtopdd.c new file mode 100644 index 00000000000..9b788eecc9a --- /dev/null +++ b/lib/libc/gdtoa/strtopdd.c @@ -0,0 +1,178 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtopdd(s, sp, dd) CONST char *s; char **sp; double *dd; +#else +strtopdd(CONST char *s, char **sp, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + ULong bits[4]; + Long exp; + int i, j, rv; + typedef union { + double d[2]; + ULong L[4]; + } U; + U *u; + + rv = strtodg(s, sp, &fpi, &exp, bits); + u = (U*)dd; + switch(rv & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + u->d[0] = u->d[1] = 0.; + break; + + case STRTOG_Normal: + u->L[_1] = (bits[1] >> 21 | bits[2] << 11) & 0xffffffffL; + u->L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & 0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & 0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + u->L[2] = u->L[3] = 0; + break; + } + u->L[2+_1] = bits[0]; + u->L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + u->L[2] = u->L[3] = 0; + u->L[_1] = bits[0]; + u->L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + u->L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + u->L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + u->L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + u->L[2+_0] = bits[1] & (1L << j) - 1; + u->L[2+_1] = bits[0]; + break; + } + if (i == 0) { + u->L[_0] = bits[2] & 0xfffff | 33 << 20; + u->L[_1] = bits[1]; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0]; + break; + } + j = 32 - i; + u->L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + u->L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + u->L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + u->L[2+_0] = 0; + u->L[2+_1] = bits[0] & (1L << j) - 1; + break; + + case STRTOG_Infinite: + u->L[_0] = u->L[2+_0] = 0x7ff00000; + u->L[_1] = u->L[2+_1] = 0; + break; + + case STRTOG_NaN: + u->L[0] = u->L[2] = d_QNAN0; + u->L[1] = u->L[3] = d_QNAN1; + } + if (rv & STRTOG_Neg) { + u->L[ _0] |= 0x80000000L; + u->L[2+_0] |= 0x80000000L; + } + return rv; + } diff --git a/lib/libc/gdtoa/strtopf.c b/lib/libc/gdtoa/strtopf.c new file mode 100644 index 00000000000..cc7c970cba4 --- /dev/null +++ b/lib/libc/gdtoa/strtopf.c @@ -0,0 +1,73 @@ +/**************************************************************** + +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" + + int +#ifdef KR_headers +strtopf(s, sp, f) CONST char *s; char **sp; float *f; +#else +strtopf(CONST char *s, char **sp, float *f) +#endif +{ + static FPI fpi = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + ULong bits[1], *L; + Long exp; + int k; + + k = strtodg(s, sp, &fpi, &exp, bits); + L = (ULong*)f; + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + return k; + } diff --git a/lib/libc/gdtoa/strtopx.c b/lib/libc/gdtoa/strtopx.c new file mode 100644 index 00000000000..4dcb06ae73c --- /dev/null +++ b/lib/libc/gdtoa/strtopx.c @@ -0,0 +1,103 @@ +/**************************************************************** + +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 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + int +#ifdef KR_headers +strtopx(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopx(CONST char *s, char **sp, void *V) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + UShort *L = (UShort*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Denormal: + L[_0] = 0; + goto normal_bits; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_0] = exp + 0x3fff + 63; + normal_bits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[0] = ldus_QNAN0; + L[1] = ldus_QNAN1; + L[2] = ldus_QNAN2; + L[3] = ldus_QNAN3; + L[4] = ldus_QNAN4; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + return k; + } diff --git a/lib/libc/gdtoa/strtopxL.c b/lib/libc/gdtoa/strtopxL.c new file mode 100644 index 00000000000..68c83d2bdae --- /dev/null +++ b/lib/libc/gdtoa/strtopxL.c @@ -0,0 +1,91 @@ +/**************************************************************** + +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 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + int +#ifdef KR_headers +strtopxL(s, sp, V) CONST char *s; char **sp; void *V; +#else +strtopxL(CONST char *s, char **sp, void *V) +#endif +{ + static FPI fpi = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + ULong bits[2]; + Long exp; + int k; + ULong *L = (ULong*)V; + + k = strtodg(s, sp, &fpi, &exp, bits); + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_2] = bits[0]; + L[_1] = bits[1]; + L[_0] = (exp + 0x3fff + 63) << 16; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + return k; + } diff --git a/lib/libc/gdtoa/strtorQ.c b/lib/libc/gdtoa/strtorQ.c new file mode 100644 index 00000000000..a9a07da04ea --- /dev/null +++ b/lib/libc/gdtoa/strtorQ.c @@ -0,0 +1,117 @@ +/**************************************************************** + +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 + + void +#ifdef KR_headers +ULtoQ(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoQ(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = (bits[3] & ~0x10000) | ((exp + 0x3fff + 112) << 16); + break; + + case STRTOG_Denormal: + L[_3] = bits[0]; + L[_2] = bits[1]; + L[_1] = bits[2]; + L[_0] = bits[3]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff0000; + L[_1] = L[_2] = L[_3] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + L[3] = ld_QNAN3; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorQ(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorQ(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 113, 1-16383-113+1, 32766-16383-113+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoQ((ULong*)L, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtord.c b/lib/libc/gdtoa/strtord.c new file mode 100644 index 00000000000..709af4c713f --- /dev/null +++ b/lib/libc/gdtoa/strtord.c @@ -0,0 +1,93 @@ +/**************************************************************** + +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" + + void +#ifdef KR_headers +ULtod(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtod(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = 0; + break; + + case STRTOG_Denormal: + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_1] = bits[0]; + L[_0] = (bits[1] & ~0x100000) | ((exp + 0x3ff + 52) << 20); + break; + + case STRTOG_Infinite: + L[_0] = 0x7ff00000; + L[_1] = 0; + break; + + case STRTOG_NaN: + L[0] = d_QNAN0; + L[1] = d_QNAN1; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtord(s, sp, rounding, d) CONST char *s; char **sp; int rounding; double *d; +#else +strtord(CONST char *s, char **sp, int rounding, double *d) +#endif +{ + static FPI fpi0 = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtod((ULong*)d, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtordd.c b/lib/libc/gdtoa/strtordd.c new file mode 100644 index 00000000000..9c2b46e65e3 --- /dev/null +++ b/lib/libc/gdtoa/strtordd.c @@ -0,0 +1,199 @@ +/**************************************************************** + +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" + + void +#ifdef KR_headers +ULtodd(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtodd(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + int i, j; + + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = 0; + break; + + case STRTOG_Normal: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 & 0xfffff + | exp + 0x3ff + 105 << 20; + exp += 0x3ff + 52; + if (bits[1] &= 0x1fffff) { + i = hi0bits(bits[1]) - 11; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i > 0) { + bits[1] = bits[1] << i | bits[0] >> 32-i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + } + else if (bits[0]) { + i = hi0bits(bits[0]) + 21; + if (i >= exp) { + i = exp - 1; + exp = 0; + } + else + exp -= i; + if (i < 32) { + bits[1] = bits[0] >> 32 - i; + bits[0] = bits[0] << i & (ULong)0xffffffffL; + } + else { + bits[1] = bits[0] << i - 32; + bits[0] = 0; + } + } + else { + L[2] = L[3] = 0; + break; + } + L[2+_1] = bits[0]; + L[2+_0] = bits[1] & 0xfffff | exp << 20; + break; + + case STRTOG_Denormal: + if (bits[3]) + goto nearly_normal; + if (bits[2]) + goto partly_normal; + if (bits[1] & 0xffe00000) + goto hardly_normal; + /* completely denormal */ + L[2] = L[3] = 0; + L[_1] = bits[0]; + L[_0] = bits[1]; + break; + + nearly_normal: + i = hi0bits(bits[3]) - 11; /* i >= 12 */ + j = 32 - i; + L[_0] = (bits[3] << i | bits[2] >> j) & 0xfffff + | 65 - i << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + + partly_normal: + i = hi0bits(bits[2]) - 11; + if (i < 0) { + j = -i; + i += 32; + L[_0] = bits[2] >> j & 0xfffff | (33 + j) << 20; + L[_1] = (bits[2] << i | bits[1] >> j) & 0xffffffffL; + L[2+_0] = bits[1] & ((ULong)1L << j) - 1; + L[2+_1] = bits[0]; + break; + } + if (i == 0) { + L[_0] = bits[2] & 0xfffff | 33 << 20; + L[_1] = bits[1]; + L[2+_0] = 0; + L[2+_1] = bits[0]; + break; + } + j = 32 - i; + L[_0] = (bits[2] << i | bits[1] >> j) & 0xfffff + | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & (1L << j) - 1; + break; + + hardly_normal: + j = 11 - hi0bits(bits[1]); + i = 32 - j; + L[_0] = bits[1] >> j & 0xfffff | j + 1 << 20; + L[_1] = (bits[1] << i | bits[0] >> j) & 0xffffffffL; + L[2+_0] = 0; + L[2+_1] = bits[0] & ((ULong)1L << j) - 1; + break; + + case STRTOG_Infinite: + L[_0] = L[2+_0] = 0x7ff00000; + L[_1] = L[2+_1] = 0; + break; + + case STRTOG_NaN: + L[0] = L[2] = d_QNAN0; + L[1] = L[3] = d_QNAN1; + break; + + case STRTOG_NaNbits: + L[_1] = (bits[1] >> 21 | bits[2] << 11) & (ULong)0xffffffffL; + L[_0] = bits[2] >> 21 | bits[3] << 11 + | (ULong)0x7ff00000L; + L[2+_1] = bits[0]; + L[2+_0] = bits[1] | (ULong)0x7ff00000L; + } + if (k & STRTOG_Neg) { + L[_0] |= 0x80000000L; + L[2+_0] |= 0x80000000L; + } + } + + int +#ifdef KR_headers +strtordd(s, sp, rounding, dd) CONST char *s; char **sp; int rounding; double *dd; +#else +strtordd(CONST char *s, char **sp, int rounding, double *dd) +#endif +{ +#ifdef Sudden_Underflow + static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 }; +#else + static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 }; +#endif + FPI *fpi, fpi1; + ULong bits[4]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtodd((ULong*)dd, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtorf.c b/lib/libc/gdtoa/strtorf.c new file mode 100644 index 00000000000..46b0ba2e424 --- /dev/null +++ b/lib/libc/gdtoa/strtorf.c @@ -0,0 +1,89 @@ +/**************************************************************** + +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" + + void +#ifdef KR_headers +ULtof(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtof(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + *L = 0; + break; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[0] = bits[0] & 0x7fffff | exp + 0x7f + 23 << 23; + break; + + case STRTOG_Denormal: + L[0] = bits[0]; + break; + + case STRTOG_Infinite: + L[0] = 0x7f800000; + break; + + case STRTOG_NaN: + L[0] = f_QNAN; + } + if (k & STRTOG_Neg) + L[0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorf(s, sp, rounding, f) CONST char *s; char **sp; int rounding; float *f; +#else +strtorf(CONST char *s, char **sp, int rounding, float *f) +#endif +{ + static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[1]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtof((ULong*)f, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtorx.c b/lib/libc/gdtoa/strtorx.c new file mode 100644 index 00000000000..23f721aa293 --- /dev/null +++ b/lib/libc/gdtoa/strtorx.c @@ -0,0 +1,119 @@ +/**************************************************************** + +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 +#define _4 4 +#endif +#ifdef IEEE_8087 +#define _0 4 +#define _1 3 +#define _2 2 +#define _3 1 +#define _4 0 +#endif + + void +#ifdef KR_headers +ULtox(L, bits, exp, k) UShort *L; ULong *bits; Long exp; int k; +#else +ULtox(UShort *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = L[3] = L[4] = 0; + break; + + case STRTOG_Denormal: + L[_0] = 0; + goto normal_bits; + + case STRTOG_Normal: + case STRTOG_NaNbits: + L[_0] = exp + 0x3fff + 63; + normal_bits: + L[_4] = (UShort)bits[0]; + L[_3] = (UShort)(bits[0] >> 16); + L[_2] = (UShort)bits[1]; + L[_1] = (UShort)(bits[1] >> 16); + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff; + L[_1] = L[_2] = L[_3] = L[_4] = 0; + break; + + case STRTOG_NaN: + L[0] = ldus_QNAN0; + L[1] = ldus_QNAN1; + L[2] = ldus_QNAN2; + L[3] = ldus_QNAN3; + L[4] = ldus_QNAN4; + } + if (k & STRTOG_Neg) + L[_0] |= 0x8000; + } + + int +#ifdef KR_headers +strtorx(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorx(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtox((UShort*)L, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/strtorxL.c b/lib/libc/gdtoa/strtorxL.c new file mode 100644 index 00000000000..ff62a61302a --- /dev/null +++ b/lib/libc/gdtoa/strtorxL.c @@ -0,0 +1,107 @@ +/**************************************************************** + +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 +#endif +#ifdef IEEE_8087 +#define _0 2 +#define _1 1 +#define _2 0 +#endif + + void +#ifdef KR_headers +ULtoxL(L, bits, exp, k) ULong *L; ULong *bits; Long exp; int k; +#else +ULtoxL(ULong *L, ULong *bits, Long exp, int k) +#endif +{ + switch(k & STRTOG_Retmask) { + case STRTOG_NoNumber: + case STRTOG_Zero: + L[0] = L[1] = L[2] = 0; + break; + + case STRTOG_Normal: + case STRTOG_Denormal: + case STRTOG_NaNbits: + L[_0] = (exp + 0x3fff + 63) << 16; + L[_1] = bits[1]; + L[_2] = bits[0]; + break; + + case STRTOG_Infinite: + L[_0] = 0x7fff << 16; + L[_1] = L[_2] = 0; + break; + + case STRTOG_NaN: + L[0] = ld_QNAN0; + L[1] = ld_QNAN1; + L[2] = ld_QNAN2; + } + if (k & STRTOG_Neg) + L[_0] |= 0x80000000L; + } + + int +#ifdef KR_headers +strtorxL(s, sp, rounding, L) CONST char *s; char **sp; int rounding; void *L; +#else +strtorxL(CONST char *s, char **sp, int rounding, void *L) +#endif +{ + static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; + FPI *fpi, fpi1; + ULong bits[2]; + Long exp; + int k; + + fpi = &fpi0; + if (rounding != FPI_Round_near) { + fpi1 = fpi0; + fpi1.rounding = rounding; + fpi = &fpi1; + } + k = strtodg(s, sp, fpi, &exp, bits); + ULtoxL((ULong*)L, bits, exp, k); + return k; + } diff --git a/lib/libc/gdtoa/sum.c b/lib/libc/gdtoa/sum.c new file mode 100644 index 00000000000..dc0c88bcfab --- /dev/null +++ b/lib/libc/gdtoa/sum.c @@ -0,0 +1,98 @@ +/**************************************************************** + +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" + + Bigint * +#ifdef KR_headers +sum(a, b) Bigint *a; Bigint *b; +#else +sum(Bigint *a, Bigint *b) +#endif +{ + Bigint *c; + ULong carry, *xc, *xa, *xb, *xe, y; +#ifdef Pack_32 + ULong z; +#endif + + if (a->wds < b->wds) { + c = b; b = a; a = c; + } + c = Balloc(a->k); + c->wds = a->wds; + carry = 0; + xa = a->x; + xb = b->x; + xc = c->x; + xe = xc + b->wds; +#ifdef Pack_32 + do { + y = (*xa & 0xffff) + (*xb & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + (*xb++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = (*xa & 0xffff) + carry; + carry = (y & 0x10000) >> 16; + z = (*xa++ >> 16) + carry; + carry = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ + *xb++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xc < xe); + xe += a->wds - b->wds; + while(xc < xe) { + y = *xa++ + carry; + carry = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif + if (carry) { + if (c->wds == c->maxwds) { + b = Balloc(c->k + 1); + Bcopy(b, c); + Bfree(c); + c = b; + } + c->x[c->wds++] = 1; + } + return c; + } diff --git a/lib/libc/gdtoa/ulp.c b/lib/libc/gdtoa/ulp.c new file mode 100644 index 00000000000..7810a5c8e64 --- /dev/null +++ b/lib/libc/gdtoa/ulp.c @@ -0,0 +1,70 @@ +/**************************************************************** + +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) double x; +#else + (double x) +#endif +{ + Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif + return a; + } diff --git a/lib/libc/gen/fpclassify.c b/lib/libc/gen/fpclassify.c index f126935961f..10a0904637b 100644 --- a/lib/libc/gen/fpclassify.c +++ b/lib/libc/gen/fpclassify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpclassify.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */ +/* $OpenBSD: fpclassify.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -62,29 +62,3 @@ __fpclassifyf(float f) return FP_NORMAL; } - -#if 0 /* XXX */ -int -__fpclassifyl(long double e) -{ - struct ieee_ext *p = (struct ieee_ext *)&e; - - if (p->ext_exp == 0) { - if (p->ext_frach == 0 && p->ext_fracl == 0) - return FP_ZERO; - else - return FP_SUBNORMAL; - } - - p->ext_frach &= ~0x80000000; /* clear sign bit */ - - if (p->ext_exp == EXT_EXP_INFNAN) { - if (p->ext_frach == 0 && p->ext_fracl == 0) - return FP_INFINITE; - else - return FP_NAN; - } - - return FP_NORMAL; -} -#endif /* XXX */ diff --git a/lib/libc/gen/isfinite.c b/lib/libc/gen/isfinite.c index 0af06c60696..0e0e8844492 100644 --- a/lib/libc/gen/isfinite.c +++ b/lib/libc/gen/isfinite.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isfinite.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */ +/* $OpenBSD: isfinite.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -33,13 +33,3 @@ __isfinitef(float f) return (p->sng_exp != SNG_EXP_INFNAN); } - -#if 0 /* XXX */ -int -__isfinitel(long double e) -{ - struct ieee_ext *p = (struct ieee_ext *)&e; - - return (p->ext_exp != EXT_EXP_INFNAN); -} -#endif /* XXX */ diff --git a/lib/libc/gen/isinf.c b/lib/libc/gen/isinf.c index f8dae2a5402..9af1ca9657b 100644 --- a/lib/libc/gen/isinf.c +++ b/lib/libc/gen/isinf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isinf.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */ +/* $OpenBSD: isinf.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -34,16 +34,3 @@ isinff(float f) return (p->sng_exp == SNG_EXP_INFNAN && p->sng_frac == 0); } - -#if 0 /* XXX */ -int -__isinfl(long double e) -{ - struct ieee_ext *p = (struct ieee_ext *)&e; - - p->ext_frach &= ~0x80000000; /* clear sign bit */ - - return (p->ext_exp == EXT_EXP_INFNAN && - p->ext_frach == 0 && p->ext_fracl == 0); -} -#endif /* XXX */ diff --git a/lib/libc/gen/isnan.c b/lib/libc/gen/isnan.c index 29566c812b7..116360369ed 100644 --- a/lib/libc/gen/isnan.c +++ b/lib/libc/gen/isnan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isnan.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */ +/* $OpenBSD: isnan.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -34,16 +34,3 @@ isnanf(float f) return (p->sng_exp == SNG_EXP_INFNAN && p->sng_frac != 0); } - -#if 0 /* XXX */ -int -__isnanl(long double e) -{ - struct ieee_ext *p = (struct ieee_ext *)&e; - - p->ext_frach &= ~0x80000000; /* clear sign bit */ - - return (p->ext_exp == EXT_EXP_INFNAN && - (p->ext_frach != 0 || p->ext_fracl != 0)); -} -#endif /* XXX */ diff --git a/lib/libc/gen/isnormal.c b/lib/libc/gen/isnormal.c index e35bddc2c35..8879218e7fe 100644 --- a/lib/libc/gen/isnormal.c +++ b/lib/libc/gen/isnormal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isnormal.c,v 1.1 2008/07/24 09:31:07 martynas Exp $ */ +/* $OpenBSD: isnormal.c,v 1.2 2008/09/07 20:36:08 martynas Exp $ */ /* * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * @@ -33,13 +33,3 @@ __isnormalf(float f) return (p->sng_exp != 0 && p->sng_exp != SNG_EXP_INFNAN); } - -#if 0 /* XXX */ -int -__isnormall(long double e) -{ - struct ieee_ext *p = (struct ieee_ext *)&e; - - return (p->ext_exp != 0 && p->ext_exp != EXT_EXP_INFNAN); -} -#endif /* XXX */ diff --git a/lib/libc/stdio/floatio.h b/lib/libc/stdio/floatio.h index 20f9801e466..97690308442 100644 --- a/lib/libc/stdio/floatio.h +++ b/lib/libc/stdio/floatio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: floatio.h,v 1.3 2003/06/02 20:18:37 millert Exp $ */ +/* $OpenBSD: floatio.h,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -40,3 +40,19 @@ #define MAXEXP 308 /* 128 bit fraction takes up 39 decimal digits; max reasonable precision */ #define MAXFRACT 39 + +/* + * MAXEXPDIG is the maximum number of decimal digits needed to store a + * floating point exponent in the largest supported format. It should + * be ceil(log10(LDBL_MAX_10_EXP)) or, if hexadecimal floating point + * conversions are supported, ceil(log10(LDBL_MAX_EXP)). But since it + * is presently never greater than 5 in practice, we fudge it. + */ +#define MAXEXPDIG 6 +#if LDBL_MAX_EXP > 999999 +#error "floating point buffers too small" +#endif + +char *__hdtoa(double, const char *, int, int *, int *, char **); +char *__hldtoa(long double, const char *, int, int *, int *, char **); +char *__ldtoa(long double *, int, int, int *, int *, char **); diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 9e651cab145..59af7eb7a22 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfprintf.c,v 1.51 2008/08/27 00:40:38 martynas Exp $ */ +/* $OpenBSD: vfprintf.c,v 1.52 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -140,22 +140,27 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap) #ifdef FLOATING_POINT +#include <float.h> #include <locale.h> #include <math.h> #include "floatio.h" -#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ #define DEFPREC 6 extern char *__dtoa(double, int, int, int *, int *, char **); extern void __freedtoa(char *); -static char *cvt(double, int, int, int *, int *, int, int *); static int exponent(char *, int, int); - -#else /* no FLOATING_POINT */ -#define BUF 40 #endif /* FLOATING_POINT */ +/* + * The size of the buffer we use as scratch space for integer + * conversions, among other things. Technically, we would need the + * most space for base 10 conversions with thousands' grouping + * characters between each pair of digits. 100 bytes is a + * conservative overestimate even for a 128-bit uintmax_t. + */ +#define BUF 100 + #define STATIC_ARG_TBL_SIZE 8 /* Size of static argument table. */ @@ -170,7 +175,6 @@ static int exponent(char *, int, int); * Flags used during conversion. */ #define ALT 0x0001 /* alternate form */ -#define HEXPREFIX 0x0002 /* add 0x or 0X prefix */ #define LADJUST 0x0004 /* left adjustment */ #define LONGDBL 0x0008 /* long double; unimplemented */ #define LONGINT 0x0010 /* long integer */ @@ -194,32 +198,52 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap) int flags; /* flags as above */ int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ - int prec; /* precision from format (%.3d), or -1 */ + int prec; /* precision from format; <0 for N/A */ char sign; /* sign prefix (' ', '+', '-', or \0) */ wchar_t wc; mbstate_t ps; #ifdef FLOATING_POINT + /* + * We can decompose the printed representation of floating + * point numbers into several parts, some of which may be empty: + * + * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ + * A B ---C--- D E F + * + * A: 'sign' holds this value if present; '\0' otherwise + * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal + * C: cp points to the string MMMNNN. Leading and trailing + * zeros are not in the string and must be added. + * D: expchar holds this character; '\0' if no exponent, e.g. %f + * F: at least two digits for decimal, at least one digit for hex + */ char *decimal_point = localeconv()->decimal_point; - int softsign; /* temporary negative sign for floats */ - double _double; /* double precision arguments %[eEfFgG] */ + int signflag; /* true if float is negative */ + union { /* floating point arguments %[aAeEfFgG] */ + double dbl; + long double ldbl; + } fparg; int expt; /* integer value of exponent */ + char expchar; /* exponent character: [eEpP\0] */ + char *dtoaend; /* pointer to end of converted digits */ int expsize; /* character count for expstr */ - int ndig; /* actual number of digits returned by cvt */ - char expstr[7]; /* buffer for exponent string */ + int lead; /* sig figs before decimal or group sep */ + int ndig; /* actual number of digits returned by dtoa */ + char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */ char *dtoaresult = NULL; #endif uintmax_t _umax; /* integer arguments %[diouxX] */ - enum { OCT, DEC, HEX } base;/* base for %[diouxX] conversion */ + enum { OCT, DEC, HEX } base; /* base for %[diouxX] conversion */ int dprec; /* a copy of prec if %[diouxX], 0 otherwise */ int realsz; /* field size expanded by dprec */ int size; /* size of converted field or string */ - char *xdigs; /* digits for %[xX] conversion */ + const char *xdigs; /* digits for %[xX] conversion */ #define NIOV 8 struct __suio uio; /* output information: summary */ struct __siov iov[NIOV];/* ... and individual io vectors */ - char buf[BUF]; /* space for %c, %[diouxX], %[eEfFgG] */ - char ox[2]; /* space for 0x hex-prefix */ + char buf[BUF]; /* buffer with space for digits of uintmax_t */ + char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */ union arg *argtable; /* args, built due to positional arg */ union arg statargtable[STATIC_ARG_TBL_SIZE]; size_t argtablesiz; @@ -237,6 +261,9 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap) static char zeroes[PADSIZE] = {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + static const char xdigs_lower[16] = "0123456789abcdef"; + static const char xdigs_upper[16] = "0123456789ABCDEF"; + /* * BEWARE, these `goto error' on error, and PAD uses `n'. */ @@ -260,6 +287,14 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap) PRINT(with, n); \ } \ } while (0) +#define PRINTANDPAD(p, ep, len, with) do { \ + n2 = (ep) - (p); \ + if (n2 > (len)) \ + n2 = (len); \ + if (n2 > 0) \ + PRINT((p), n2); \ + PAD((len) - (n2 > 0 ? n2 : 0), (with)); \ +} while(0) #define FLUSH() do { \ if (uio.uio_resid && __sprint(fp, &uio)) \ goto error; \ @@ -386,6 +421,7 @@ vfprintf(FILE *fp, const char *fmt0, __va_list ap) width = 0; prec = -1; sign = '\0'; + ox[1] = '\0'; rflag: ch = *fmt++; reswitch: switch (ch) { @@ -520,82 +556,122 @@ reswitch: switch (ch) { base = DEC; goto number; #ifdef FLOATING_POINT + case 'a': + case 'A': + if (ch == 'a') { + ox[1] = 'x'; + xdigs = xdigs_lower; + expchar = 'p'; + } else { + ox[1] = 'X'; + xdigs = xdigs_upper; + expchar = 'P'; + } + if (prec >= 0) + prec++; + if (dtoaresult) + __freedtoa(dtoaresult); + if (flags & LONGDBL) { + fparg.ldbl = GETARG(long double); + dtoaresult = cp = + __hldtoa(fparg.ldbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } else { + fparg.dbl = GETARG(double); + dtoaresult = cp = + __hdtoa(fparg.dbl, xdigs, prec, + &expt, &signflag, &dtoaend); + } + if (prec < 0) + prec = dtoaend - cp; + if (expt == INT_MAX) + ox[1] = '\0'; + goto fp_common; case 'e': case 'E': + expchar = ch; + if (prec < 0) /* account for digit before decpt */ + prec = DEFPREC + 1; + else + prec++; + goto fp_begin; case 'f': case 'F': + expchar = '\0'; + goto fp_begin; case 'g': case 'G': - if (prec == -1) { + expchar = ch - ('g' - 'e'); + if (prec == 0) + prec = 1; +fp_begin: + if (prec < 0) prec = DEFPREC; - } else if ((ch == 'g' || ch == 'G') && prec == 0) { - prec = 1; - } - + if (dtoaresult) + __freedtoa(dtoaresult); if (flags & LONGDBL) { - _double = (double) GETARG(long double); + fparg.ldbl = GETARG(long double); + dtoaresult = cp = + __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); } else { - _double = GETARG(double); - } - - /* do this before tricky precision changes */ - if (isinf(_double)) { - if (_double < 0) - sign = '-'; - if (ch == 'E' || ch == 'F' || ch == 'G') - cp = "INF"; - else - cp = "inf"; - size = 3; - flags &= ~ZEROPAD; - break; - } - if (isnan(_double)) { - if (ch == 'E' || ch == 'F' || ch == 'G') - cp = "NAN"; - else - cp = "nan"; - size = 3; + fparg.dbl = GETARG(double); + dtoaresult = cp = + __dtoa(fparg.dbl, expchar ? 2 : 3, prec, + &expt, &signflag, &dtoaend); + if (expt == 9999) + expt = INT_MAX; + } +fp_common: + if (signflag) + sign = '-'; + if (expt == INT_MAX) { /* inf or nan */ + if (*cp == 'N') { + cp = (ch >= 'a') ? "nan" : "NAN"; + sign = '\0'; + } else + cp = (ch >= 'a') ? "inf" : "INF"; + size = 3; flags &= ~ZEROPAD; - break; - } - + break; + } flags |= FPT; - if (dtoaresult) - __freedtoa(dtoaresult); - dtoaresult = cp = cvt(_double, prec, flags, &softsign, - &expt, ch, &ndig); - if (ch == 'g' || ch == 'G') { - if (expt <= -4 || expt > prec) - ch = (ch == 'g') ? 'e' : 'E'; - else - ch = 'g'; - } - if (ch == 'e' || ch == 'E') { /* 'e' or 'E' fmt */ - --expt; - expsize = exponent(expstr, expt, ch); - size = expsize + ndig; - if (ndig > 1 || flags & ALT) - ++size; - } else if (ch == 'f' || ch == 'F') { - /* 'f' or 'F' fmt */ - if (expt > 0) { - size = expt; - if (prec || flags & ALT) - size += prec + 1; - } else { /* "0.X" */ - size = prec + 2; + ndig = dtoaend - cp; + if (ch == 'g' || ch == 'G') { + if (expt > -4 && expt <= prec) { + /* Make %[gG] smell like %[fF] */ + expchar = '\0'; + if (flags & ALT) + prec -= expt; + else + prec = ndig - expt; + if (prec < 0) + prec = 0; + } else { + /* + * Make %[gG] smell like %[eE], but + * trim trailing zeroes if no # flag. + */ + if (!(flags & ALT)) + prec = ndig; } - } else if (expt >= ndig) { /* fixed g fmt */ - size = expt; - if (flags & ALT) - ++size; + } + if (expchar) { + expsize = exponent(expstr, expt - 1, expchar); + size = expsize + prec; + if (prec > 1 || flags & ALT) + ++size; } else { - size = ndig + (expt > 0 ? 1 : 2 - expt); + /* space for digits before decimal point */ + if (expt > 0) + size = expt; + else /* "0" */ + size = 1; + /* space for decimal pt and following digits */ + if (prec || flags & ALT) + size += prec + 1; + lead = expt; } - - if (softsign) - sign = '-'; break; #endif /* FLOATING_POINT */ case 'n': @@ -634,9 +710,8 @@ reswitch: switch (ch) { /* NOSTRICT */ _umax = (u_long)GETARG(void *); base = HEX; - xdigs = "0123456789abcdef"; - flags |= HEXPREFIX; - ch = 'x'; + xdigs = xdigs_lower; + ox[1] = 'x'; goto nosign; case 's': if ((cp = GETARG(char *)) == NULL) @@ -667,15 +742,15 @@ reswitch: switch (ch) { base = DEC; goto nosign; case 'X': - xdigs = "0123456789ABCDEF"; + xdigs = xdigs_upper; goto hex; case 'x': - xdigs = "0123456789abcdef"; + xdigs = xdigs_lower; hex: _umax = UARG(); base = HEX; /* leading 0x/X only if non-zero */ if (flags & ALT && _umax != 0) - flags |= HEXPREFIX; + ox[1] = ch; /* unsigned conversions */ nosign: sign = '\0'; @@ -733,6 +808,8 @@ number: if ((dprec = prec) >= 0) } } size = buf + BUF - cp; + if (size > BUF) /* should never happen */ + abort(); skipsize: break; default: /* "%?" prints ?, unless ? is NUL */ @@ -763,7 +840,7 @@ number: if ((dprec = prec) >= 0) realsz = dprec > size ? dprec : size; if (sign) realsz++; - else if (flags & HEXPREFIX) + if (ox[1]) realsz+= 2; /* right-adjusting blank padding */ @@ -771,11 +848,10 @@ number: if ((dprec = prec) >= 0) PAD(width - realsz, blanks); /* prefix */ - if (sign) { + if (sign) PRINT(&sign, 1); - } else if (flags & HEXPREFIX) { + if (ox[1]) { /* ox[1] is either x, X, or \0 */ ox[0] = '0'; - ox[1] = ch; PRINT(ox, 2); } @@ -791,41 +867,28 @@ number: if ((dprec = prec) >= 0) if ((flags & FPT) == 0) { PRINT(cp, size); } else { /* glue together f_p fragments */ - if (ch >= 'f' || ch == 'F') { /* 'f', 'g' or 'F' */ - if (_double == 0) { - /* kludge for __dtoa irregularity */ - PRINT("0", 1); - if (expt < ndig || (flags & ALT) != 0) { + if (!expchar) { /* %[fF] or sufficiently short %[gG] */ + if (expt <= 0) { + PRINT(zeroes, 1); + if (prec || flags & ALT) PRINT(decimal_point, 1); - PAD(ndig - 1, zeroes); - } - } else if (expt <= 0) { - PRINT("0", 1); - PRINT(decimal_point, 1); PAD(-expt, zeroes); - PRINT(cp, ndig); - } else if (expt >= ndig) { - PRINT(cp, ndig); - PAD(expt - ndig, zeroes); - if (flags & ALT) + /* already handled initial 0's */ + prec += expt; + } else { + PRINTANDPAD(cp, dtoaend, lead, zeroes); + cp += lead; + if (prec || flags & ALT) PRINT(".", 1); - } else { - PRINT(cp, expt); - cp += expt; - PRINT(".", 1); - PRINT(cp, ndig-expt); } - } else { /* 'e' or 'E' */ - if (ndig > 1 || flags & ALT) { - ox[0] = *cp++; - ox[1] = '.'; - PRINT(ox, 2); - if (_double) { - PRINT(cp, ndig-1); - } else {/* 0.[0..] */ - /* __dtoa irregularity */ - PAD(ndig - 1, zeroes); - } + PRINTANDPAD(cp, dtoaend, prec, zeroes); + } else { /* %[eE] or sufficiently long %[gG] */ + if (prec > 1 || flags & ALT) { + buf[0] = *cp++; + buf[1] = '.'; + PRINT(buf, 2); + PRINT(cp, ndig-1); + PAD(prec - ndig, zeroes); } else { /* XeYYY */ PRINT(cp, 1); } @@ -1076,6 +1139,8 @@ reswitch: switch (ch) { ADDSARG(); break; #ifdef FLOATING_POINT + case 'a': + case 'A': case 'e': case 'E': case 'f': @@ -1266,49 +1331,11 @@ __grow_type_table(unsigned char **typetable, int *tablesize) #ifdef FLOATING_POINT - -static char * -cvt(double value, int ndigits, int flags, int *sign, int *decpt, int ch, - int *length) -{ - int mode; - char *digits, *bp, *rve; - - if (ch == 'f' || ch == 'F') { - mode = 3; /* ndigits after the decimal point */ - } else { - /* To obtain ndigits after the decimal point for the 'e' - * and 'E' formats, round to ndigits + 1 significant - * figures. - */ - if (ch == 'e' || ch == 'E') { - ndigits++; - } - mode = 2; /* ndigits significant digits */ - } - - digits = __dtoa(value, mode, ndigits, decpt, sign, &rve); - if ((ch != 'g' && ch != 'G') || flags & ALT) {/* Print trailing zeros */ - bp = digits + ndigits; - if (ch == 'f' || ch == 'F') { - if (*digits == '0' && value) - *decpt = -ndigits + 1; - bp += *decpt; - } - if (value == 0) /* kludge for __dtoa irregularity */ - rve = bp; - while (rve < bp) - *rve++ = '0'; - } - *length = rve - digits; - return (digits); -} - static int exponent(char *p0, int exp, int fmtch) { char *p, *t; - char expbuf[MAXEXP]; + char expbuf[MAXEXPDIG]; p = p0; *p++ = fmtch; @@ -1317,16 +1344,23 @@ exponent(char *p0, int exp, int fmtch) *p++ = '-'; } else *p++ = '+'; - t = expbuf + MAXEXP; + t = expbuf + MAXEXPDIG; if (exp > 9) { do { *--t = to_char(exp % 10); } while ((exp /= 10) > 9); *--t = to_char(exp); - for (; t < expbuf + MAXEXP; *p++ = *t++) + for (; t < expbuf + MAXEXPDIG; *p++ = *t++) /* nothing */; } else { - *p++ = '0'; + /* + * Exponents for decimal floating point conversions + * (%[eEgG]) must be at least two characters long, + * whereas exponents for hexadecimal conversions can + * be only one character long. + */ + if (fmtch == 'e' || fmtch == 'E') + *p++ = '0'; *p++ = to_char(exp); } return (p - p0); diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 09db4ce7935..ab8bd39f07b 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.39 2008/08/22 17:14:56 otto Exp $ +# $OpenBSD: Makefile.inc,v 1.40 2008/09/07 20:36:08 martynas Exp $ # stdlib sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/stdlib ${LIBCSRCDIR}/stdlib @@ -7,7 +7,7 @@ SRCS+= a64l.c abort.c atexit.c atoi.c atof.c atol.c atoll.c bsearch.c \ cfree.c exit.c ecvt.c gcvt.c getenv.c getopt_long.c \ getsubopt.c hcreate.c heapsort.c imaxabs.c imaxdiv.c l64a.c llabs.c \ lldiv.c lsearch.c malloc.c merge.c putenv.c qsort.c radixsort.c rand.c \ - random.c realpath.c setenv.c strtoimax.c strtod.c strtof.c strtol.c \ + random.c realpath.c setenv.c strtoimax.c strtol.c \ strtoll.c strtonum.c strtoul.c strtoull.c strtoumax.c system.c \ tfind.c tsearch.c _rand48.c drand48.c erand48.c jrand48.c lcong48.c \ lrand48.c mrand48.c nrand48.c seed48.c srand48.c qabs.c qdiv.c _Exit.c diff --git a/lib/libc/stdlib/strtod.c b/lib/libc/stdlib/strtod.c deleted file mode 100644 index 4dc3d65a267..00000000000 --- a/lib/libc/stdlib/strtod.c +++ /dev/null @@ -1,2459 +0,0 @@ -/* $OpenBSD: strtod.c,v 1.30 2006/10/30 18:30:52 deraadt Exp $ */ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991 by AT&T. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to - David M. Gay - AT&T Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-2070 - U.S.A. - dmg@research.att.com or research!dmg - */ - -/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -/* - * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define Long int on machines with 32-bit ints and 64-bit longs. - * #define Sudden_Underflow for IEEE-format machines without gradual - * underflow (i.e., that flush to zero on underflow). - * #define IBM for IBM mainframe-style floating-point arithmetic. - * #define VAX for VAX-style floating-point arithmetic. - * #define Unsigned_Shifts if >> does treats its left operand as unsigned. - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. - * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. - * #define ROUND_BIASED for IEEE-format with biased rounding. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision - * integer arithmetic. Whether this speeds things up or slows things - * down depends on the machine and the number being converted. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. - */ - -#include <sys/types.h> -#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \ - defined(__mips__) || defined(__mips64__) || defined(__ns32k__) || \ - defined(__alpha__) || defined(__powerpc__) || defined(__m88k__) || \ - defined(__hppa__) || defined(__amd64__) || defined(__sh__) || \ - defined(__sparc64__) || \ - (defined(__arm__) && defined(__VFP_FP__)) - -#if BYTE_ORDER == BIG_ENDIAN -#define IEEE_BIG_ENDIAN -#else -#define IEEE_LITTLE_ENDIAN -#endif -#endif - -#if defined(__arm__) && !defined(__VFP_FP__) -/* - * Although the CPU is little endian the FP has different - * byte and word endianness. The byte order is still little endian - * but the word order is big endian. - */ -#define IEEE_BIG_ENDIAN -#endif - -#ifdef __vax__ -#define VAX -#endif - -#define Long int32_t -#define ULong u_int32_t - -#ifdef DEBUG -#include "stdio.h" -#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} -#endif - -#include "thread_private.h" - -_THREAD_PRIVATE_KEY(dtoa); -_THREAD_PRIVATE_KEY(pow5mult); - -#ifdef __cplusplus -#include "malloc.h" -#include "memory.h" -#else -#include "stdlib.h" -#include "string.h" -#include "locale.h" -#endif - -#ifdef MALLOC -extern void *MALLOC(size_t); -#else -#define MALLOC malloc -#endif - -#include "ctype.h" -#include "errno.h" - -#ifdef Bad_float_h -#ifdef IEEE_BIG_ENDIAN -#define IEEE_ARITHMETIC -#endif -#ifdef IEEE_LITTLE_ENDIAN -#define IEEE_ARITHMETIC -#endif - -#ifdef IEEE_ARITHMETIC -#define DBL_DIG 15 -#define DBL_MAX_10_EXP 308 -#define DBL_MAX_EXP 1024 -#define FLT_RADIX 2 -#define FLT_ROUNDS 1 -#define DBL_MAX 1.7976931348623157e+308 -#endif - -#ifdef IBM -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 75 -#define DBL_MAX_EXP 63 -#define FLT_RADIX 16 -#define FLT_ROUNDS 0 -#define DBL_MAX 7.2370055773322621e+75 -#endif - -#ifdef VAX -#define DBL_DIG 16 -#define DBL_MAX_10_EXP 38 -#define DBL_MAX_EXP 127 -#define FLT_RADIX 2 -#define FLT_ROUNDS 1 -#define DBL_MAX 1.7014118346046923e+38 -#endif - -#ifndef LONG_MAX -#define LONG_MAX 2147483647 -#endif -#else -#include "float.h" -#endif -#ifndef __MATH_H__ -#include "math.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef CONST -#define CONST const -#endif - -#ifdef Unsigned_Shifts -#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000; -#else -#define Sign_Extend(a,b) /*no-op*/ -#endif - -#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + \ - defined(IBM) != 1 -#error Exactly one of IEEE_LITTLE_ENDIAN IEEE_BIG_ENDIAN, VAX, or IBM should be defined. -#endif - -typedef union { - double d; - ULong ul[2]; -} _double; -#define value(x) ((x).d) -#ifdef IEEE_LITTLE_ENDIAN -#define word0(x) ((x).ul[1]) -#define word1(x) ((x).ul[0]) -#else -#define word0(x) ((x).ul[0]) -#define word1(x) ((x).ul[1]) -#endif - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) - */ -#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) -#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \ -((unsigned short *)a)[0] = (unsigned short)c, a++) -#else -#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \ -((unsigned short *)a)[1] = (unsigned short)c, a++) -#endif - -/* #define P DBL_MANT_DIG */ -/* Ten_pmax = floor(P*log(2)/log(5)) */ -/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ -/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ -/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ - -#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define IEEE_Arith -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 -#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ -#else -#undef Sudden_Underflow -#define Sudden_Underflow -#ifdef IBM -#define Exp_shift 24 -#define Exp_shift1 24 -#define Exp_msk1 0x1000000 -#define Exp_msk11 0x1000000 -#define Exp_mask 0x7f000000 -#define P 14 -#define Bias 65 -#define Exp_1 0x41000000 -#define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ -#define Frac_mask 0xffffff -#define Frac_mask1 0xffffff -#define Bletch 4 -#define Ten_pmax 22 -#define Bndry_mask 0xefffff -#define Bndry_mask1 0xffffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 4 -#define Tiny0 0x100000 -#define Tiny1 0 -#define Quick_max 14 -#define Int_max 15 -#else /* VAX */ -#define Exp_shift 23 -#define Exp_shift1 7 -#define Exp_msk1 0x80 -#define Exp_msk11 0x800000 -#define Exp_mask 0x7f80 -#define P 56 -#define Bias 129 -#define Exp_1 0x40800000 -#define Exp_11 0x4080 -#define Ebits 8 -#define Frac_mask 0x7fffff -#define Frac_mask1 0xffff007f -#define Ten_pmax 24 -#define Bletch 2 -#define Bndry_mask 0xffff007f -#define Bndry_mask1 0xffff007f -#define LSB 0x10000 -#define Sign_bit 0x8000 -#define Log2P 1 -#define Tiny0 0x80 -#define Tiny1 0 -#define Quick_max 15 -#define Int_max 15 -#endif -#endif - -#ifndef IEEE_Arith -#define ROUND_BIASED -#endif - -#ifdef RND_PRODQUOT -#define rounded_product(a,b) a = rnd_prod(a, b) -#define rounded_quotient(a,b) a = rnd_quot(a, b) -extern double rnd_prod(double, double), rnd_quot(double, double); -#else -#define rounded_product(a,b) a *= b -#define rounded_quotient(a,b) a /= b -#endif - -#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) -#define Big1 0xffffffff - -#ifndef Just_16 -/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per Long. - */ -#ifndef Pack_32 -#define Pack_32 -#endif -#endif - -#define Kmax 15 - -#ifdef __cplusplus -extern "C" double strtod(const char *s00, char **se); -extern "C" char *__dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); -#endif - - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; - - typedef struct Bigint Bigint; - - static Bigint *freelist[Kmax+1]; - -#define PRIVATE_MEM 2304 -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) - static double private_mem[PRIVATE_mem], *pmem_next = private_mem; - - static Bigint * -Balloc(int k) -{ - int x; - unsigned int len; - Bigint *rv; - - _THREAD_PRIVATE_MUTEX_LOCK(dtoa); - if ((rv = freelist[k])) { - freelist[k] = rv->next; - } - else { - x = 1 << k; - len = (sizeof(Bigint) + (x-1)*sizeof(Long) + sizeof(double) - 1) - /sizeof(double); - if (pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint *)pmem_next; - pmem_next += len; - } - else - rv = (Bigint *)MALLOC(len *sizeof(double)); - rv->k = k; - rv->maxwds = x; - } - _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa); - rv->sign = rv->wds = 0; - return rv; - } - - static void -Bfree(Bigint *v) -{ - if (v) { - _THREAD_PRIVATE_MUTEX_LOCK(dtoa); - v->next = freelist[v->k]; - freelist[v->k] = v; - _THREAD_PRIVATE_MUTEX_UNLOCK(dtoa); - } - } - -#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ -y->wds*sizeof(Long) + 2*sizeof(int)) - -/* return value is only used as a simple string, so mis-aligned parts - * inside the Bigint are not at risk on strict align architectures - */ - static char * -rv_alloc(int i) -{ - 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 (char *)(r+1); - } - - static char * -nrv_alloc(char *s, char **rve, int n) -{ - char *rv, *t; - - t = rv = rv_alloc(n); - while((*t = *s++) !=0) - t++; - if (rve) - *rve = t; - return rv; - } - - void -__freedtoa(char *s) -{ - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); - } - - static Bigint * -multadd(Bigint *b, int m, int a) /* multiply by m and add a */ -{ - int i, wds; - ULong *x, y; -#ifdef Pack_32 - ULong xi, z; -#endif - Bigint *b1; - - wds = b->wds; - x = b->x; - i = 0; - do { -#ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + a; - z = (xi >> 16) * m + (y >> 16); - a = (int)(z >> 16); - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + a; - a = (int)(y >> 16); - *x++ = y & 0xffff; -#endif - } - while(++i < wds); - if (a) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = a; - b->wds = wds; - } - return b; - } - - static Bigint * -s2b(CONST char *s, int nd0, int nd, ULong y9) -{ - Bigint *b; - int i, k; - Long x, y; - - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; -#ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int -hi0bits(ULong x) -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } - - static int -lo0bits(ULong *y) -{ - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!(x & 1)) - return 32; - } - *y = x; - return k; - } - - static Bigint * -i2b(int i) -{ - Bigint *b; - - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } - - static Bigint * -mult(Bigint *a, Bigint *b) -{ - Bigint *c; - int k, wa, wb, wc; - ULong carry, y, z; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; -#ifdef Pack_32 - ULong z2; -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; -#ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if ((y = *xb >> 16)) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * -pow5mult(Bigint *b, int k) -{ - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ - _THREAD_PRIVATE_MUTEX_LOCK(pow5mult); - p5 = p5s = i2b(625); - p5->next = 0; - _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult); - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { - _THREAD_PRIVATE_MUTEX_LOCK(pow5mult); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult); - } - p5 = p51; - } - return b; - } - - static Bigint * -lshift(Bigint *b, int k) -{ - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; - -#ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; -#ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int -cmp(Bigint *a, Bigint *b) -{ - ULong *xa, *xa0, *xb, *xb0; - int i, j; - - i = a->wds; - j = b->wds; -#ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * -diff(Bigint *a, Bigint *b) -{ - Bigint *c; - int i, wa, wb; - Long borrow, y; /* We need signed shifts here. */ - ULong *xa, *xae, *xb, *xbe, *xc; -#ifdef Pack_32 - Long z; -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; -#ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) - (*xb++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*xa++ >> 16) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *xc++ = y & 0xffff; - } -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double -ulp(double _x) -{ - _double x; - Long L; - _double a; - - value(x) = _x; - 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 value(a); - } - - static double -b2d(Bigint *a, int *e) -{ - ULong *xa, *xa0, w, y, z; - int k; - _double d; -#ifdef VAX - ULong d0, d1; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; -#ifdef DEBUG - if (!y) Bug("zero y in b2d"); -#endif - k = hi0bits(y); - *e = 32 - k; -#ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; - w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: -#ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; -#else -#undef d0 -#undef d1 -#endif - return value(d); - } - - static Bigint * -d2b(double _d, int *e, int *bits) -{ - Bigint *b; - int de, i, k; - ULong *x, y, z; - _double d; -#ifdef VAX - ULong d0, d1; -#endif - - value(d) = _d; -#ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; -#else -#define d0 word0(d) -#define d1 word1(d) -#endif - -#ifdef Pack_32 - b = Balloc(1); -#else - b = Balloc(2); -#endif - x = b->x; - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#ifndef IBM - z |= Exp_msk11; -#endif -#else - if (de = (int)(d0 >> Exp_shift)) - z |= Exp_msk1; -#endif -#ifdef Pack_32 - if (y = d1) { - if (k = lo0bits(&y)) { - x[0] = y | z << 32 - k; - z >>= k; - } - else - x[0] = y; - i = b->wds = (x[1] = z) ? 2 : 1; - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - x[0] = z; - i = b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { -#ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; -#endif -#ifndef Sudden_Underflow - if (de) { -#endif -#ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); -#else - *e = de - Bias - (P-1) + k; - *bits = P - k; -#endif -#ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; -#ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); -#else - *bits = (i+2)*16 - hi0bits(x[i]); -#endif - } -#endif - return b; - } -#undef d0 -#undef d1 - - static double -ratio(Bigint *a, Bigint *b) -{ - _double da, db; - int k, ka, kb; - - value(da) = b2d(a, &ka); - value(db) = b2d(b, &kb); -#ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); -#else - k = ka - kb + 16*(a->wds - b->wds); -#endif -#ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - da *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - db *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return value(da) / value(db); - } - -static CONST double -tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -#ifdef VAX - , 1e23, 1e24 -#endif - }; - -#ifdef IEEE_Arith -static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; -#define n_bigtens 5 -#else -#ifdef IBM -static CONST double bigtens[] = { 1e16, 1e32, 1e64 }; -static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; -#define n_bigtens 3 -#else -static CONST double bigtens[] = { 1e16, 1e32 }; -static CONST double tinytens[] = { 1e-16, 1e-32 }; -#define n_bigtens 2 -#endif -#endif - - double -strtod(CONST char *s00, char **se) -{ - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj; - /* - * volatile forces mem update for FPUs where reg size != sizeof double, - * which should trigger ERANGE in the case of underflow. - */ - volatile _double rv; - _double rv0; - Long L; - ULong y, z; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; - - CONST char decimal_point = localeconv()->decimal_point[0]; - - sign = nz0 = nz = 0; - value(rv) = 0.; - - - for(s = s00; isspace((unsigned char) *s); s++) - ; - - if (*s == '-') { - sign = 1; - s++; - } else if (*s == '+') { - s++; - } - - if (*s == '\0') { - s = s00; - goto ret; - } - - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - if (c == decimal_point) { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - s = s00; - goto ret; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) - s = s00; - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - value(rv) = y; - if (k > 9) - value(rv) = tens[k - 9] * value(rv) + z; - bd0 = 0; - if (nd <= DBL_DIG -#ifndef RND_PRODQUOT - && FLT_ROUNDS == 1 -#endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { -#ifdef VAX - goto vax_ovfl_check; -#else - /* value(rv) = */ rounded_product(value(rv), - tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - value(rv) *= tens[i]; -#ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* value(rv) = */ rounded_product(value(rv), - tens[e]); - if ((word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(rv) += P*Exp_msk1; -#else - /* value(rv) = */ rounded_product(value(rv), - tens[e]); -#endif - goto ret; - } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { - /* value(rv) = */ rounded_quotient(value(rv), - tens[-e]); - goto ret; - } -#endif - } - e1 += nd - k; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if (i = e1 & 15) - value(rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - errno = ERANGE; -#ifndef Bad_float_h - value(rv) = HUGE_VAL; -#else - /* Can't trust HUGE_VAL */ -#ifdef IEEE_Arith - word0(rv) = Exp_mask; - word1(rv) = 0; -#else - word0(rv) = Big0; - word1(rv) = Big1; -#endif -#endif - if (bd0) - goto retfree; - goto ret; - } - if (e1 >>= 4) { - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - value(rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - value(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; - } - else - word0(rv) += P*Exp_msk1; - } - - } - } - else if (e1 < 0) { - e1 = -e1; - if (i = e1 & 15) - value(rv) /= tens[i]; - if (e1 &= ~15) { - e1 >>= 4; - if (e1 >= 1 << n_bigtens) - goto undfl; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - value(rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - value(rv0) = value(rv); - value(rv) *= tinytens[j]; - if (!value(rv)) { - value(rv) = 2.*value(rv0); - value(rv) *= tinytens[j]; - if (!value(rv)) { - undfl: - value(rv) = 0.; - errno = ERANGE; - if (bd0) - goto retfree; - goto ret; - } - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(value(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; -#ifdef Sudden_Underflow -#ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); -#else - j = P + 1 - bbbits; -#endif -#else - i = bbe + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j = bbe + (P-Emin); - else - j = P + 1 - bbbits; -#endif - bb2 += j; - bd2 += j; - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) - break; - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == 0xffffffff) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 -#ifdef IBM - | Exp_msk1 >> 4 -#endif - ; - word1(rv) = 0; - break; - } - } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow - L = word0(rv) & Exp_mask; -#ifdef IBM - if (L < Exp_msk1) -#else - if (L <= Exp_msk1) -#endif - goto undfl; - L -= Exp_msk1; -#else - L = (word0(rv) & Exp_mask) - Exp_msk1; -#endif - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; -#ifdef IBM - goto cont; -#else - break; -#endif - } -#ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) - break; -#endif - if (dsign) - value(rv) += ulp(value(rv)); -#ifndef ROUND_BIASED - else { - value(rv) -= ulp(value(rv)); -#ifndef Sudden_Underflow - if (!value(rv)) - goto undfl; -#endif - } -#endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { -#ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch(FLT_ROUNDS) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (FLT_ROUNDS == 0) - aadj1 += 0.5; -#endif - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - value(rv0) = value(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(value(rv)); - value(rv) += adj; - if ((word0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) - goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; - goto cont; - } - else - word0(rv) += P*Exp_msk1; - } - else { -#ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - value(rv0) = value(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(value(rv)); - value(rv) += adj; -#ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) - goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; - goto cont; - } - else - word0(rv) -= P*Exp_msk1; - } - else { - adj = aadj1 * ulp(value(rv)); - value(rv) += adj; - } -#else - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj >= 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(value(rv)); - value(rv) += adj; -#endif - } - z = word0(rv) & Exp_mask; - if (y == z) { - /* Can we stop now? */ - L = aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -value(rv) : value(rv); - } - - static int -quorem(Bigint *b, Bigint *S) -{ - int n; - Long borrow, y; - ULong carry, q, ys; - ULong *bx, *bxe, *sx, *sxe; -#ifdef Pack_32 - Long z; - ULong si, zs; -#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 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 >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#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 Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - z = (*bx >> 16) - (zs & 0xffff) + borrow; - borrow = z >> 16; - Sign_Extend(borrow, z); - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) + borrow; - borrow = y >> 16; - Sign_Extend(borrow, y); - *bx++ = y & 0xffff; -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. - */ - - char * -__dtoa(double _d, int mode, int ndigits, int *decpt, int *sign, char **rve) -{ - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4-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, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; -#ifndef Sudden_Underflow - int denorm; - ULong x; -#endif - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - double ds; - char *s, *s0; - _double d, d2, eps; - - value(d) = _d; - - if (word0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; - -#if defined(IEEE_Arith) + defined(VAX) -#ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) -#else - if (word0(d) == 0x8000) -#endif - { - /* Infinity or NaN */ - *decpt = 9999; -#ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); -#endif - return nrv_alloc("NaN", rve, 3); - } -#endif -#ifdef IBM - value(d) += 0; /* normalize */ -#endif - if (!value(d)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } - - b = d2b(value(d), &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); -#else - if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { -#endif - value(d2) = value(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; -#ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - value(d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; -#ifdef IBM - i <<= 2; - i += j; -#endif -#ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 - : word1(d) << 32 - i; - value(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (value(d2)-1.5)*0.289529654602168 + 0.1760912590558 + - i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (value(d) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; - try_quick = 1; - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - value(d2) = value(d); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - value(d) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - value(d) /= ds; - } - else if (j1 = -k) { - value(d) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - value(d) *= bigtens[i]; - } - } - if (k_check && value(d) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - value(d) *= 10.; - ieps++; - } - value(eps) = ieps*value(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - value(d) -= 5.; - if (value(d) > value(eps)) - goto one_digit; - if (value(d) < -value(eps)) - goto no_digits; - goto fast_failed; - } -#ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - value(eps) = 0.5/tens[ilim-1] - value(eps); - for(i = 0;;) { - L = value(d); - value(d) -= L; - *s++ = '0' + (int)L; - if (value(d) < value(eps)) - goto ret1; - if (1. - value(d) < value(eps)) - goto bump_up; - if (++i >= ilim) - break; - value(eps) *= 10.; - value(d) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - value(eps) *= tens[ilim-1]; - for(i = 1;; i++, value(d) *= 10.) { - L = value(d); - value(d) -= L; - *s++ = '0' + (int)L; - if (i == ilim) { - if (value(d) > 0.5 + value(eps)) - goto bump_up; - else if (value(d) < 0.5 - value(eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } -#ifndef No_leftright - } -#endif - fast_failed: - s = s0; - value(d) = value(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 || value(d) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++) { - L = value(d) / ds; - value(d) -= L*ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (value(d) < 0) { - L--; - value(d) += ds; - } -#endif - *s++ = '0' + (int)L; - if (i == ilim) { - value(d) += value(d); - if (value(d) > ds || value(d) == ds && L & 1) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - if (!(value(d) *= 10.)) - break; - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - if (mode < 2) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : -#endif -#ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - } - 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) - 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. */ - - if (mode < 2) { - if (!word1(d) && !(word0(d) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(d) & Exp_mask -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - else - spec_case = 0; - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ -#ifdef Pack_32 - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && mode > 2) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); -#ifndef ROUND_BIASED - if (j1 == 0 && !mode && !(word1(d) & 1)) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } -#endif - if (j < 0 || j == 0 && !mode -#ifndef ROUND_BIASED - && !(word1(d) & 1) -#endif - ) { - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) - && dig++ == '9') - goto round_9_up; - } - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *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 */ - - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: - Bfree(b); - if (s == s0) { /* don't return empty string */ - *s++ = '0'; - k = 0; - } - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } -#ifdef __cplusplus -} -#endif diff --git a/lib/libm/Makefile b/lib/libm/Makefile index 8e259df2088..575b40c3880 100644 --- a/lib/libm/Makefile +++ b/lib/libm/Makefile @@ -1,5 +1,5 @@ # $NetBSD: Makefile,v 1.28 1995/11/20 22:06:19 jtc Exp $ -# $OpenBSD: Makefile,v 1.53 2008/07/30 08:02:34 jmc Exp $ +# $OpenBSD: Makefile,v 1.54 2008/09/07 20:36:08 martynas Exp $ # # @(#)Makefile 5.1beta 93/09/24 # @@ -11,42 +11,10 @@ # software is freely granted, provided that this notice # is preserved. # ==================================================== -# -# -# -# There are two options in making libm at fdlibm compile time: -# _IEEE_LIBM --- IEEE libm; smaller, and somewhat faster -# _MULTI_LIBM --- Support multi-standard at runtime by -# imposing wrapper functions defined in -# fdlibm.h: -# _IEEE_MODE -- IEEE -# _XOPEN_MODE -- X/OPEN -# _POSIX_MODE -- POSIX/ANSI -# _SVID3_MODE -- SVID -# -# Here is how to set up CFLAGS to create the desired libm at -# compile time: -# -# CFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended) -# CFLAGS = -D_SVID3_MODE ... Multi-standard supported -# libm with SVID as the -# default standard -# CFLAGS = -D_XOPEN_MODE ... Multi-standard supported -# libm with XOPEN as the -# default standard -# CFLAGS = -D_POSIX_MODE ... Multi-standard supported -# libm with POSIX as the -# default standard -# CFLAGS = ... Multi-standard supported -# libm with IEEE as the -# default standard -# # For NOPROFILE and NOPIC .include <bsd.own.mk> -CFLAGS+= -D__LIBM_PRIVATE -D_USE_WRITE - .if (${MACHINE_ARCH} == "sparc") CFLAGS+= -O0 .endif @@ -94,10 +62,6 @@ ARCH_SRCS = n_atan2.S n_cabs.S n_cbrt.S n_sincos.S n_tan.S n_support.S .PATH: ${.CURDIR}/src .PATH: ${.CURDIR}/noieee_src -.if (${MACHINE_ARCH} != "vax") -CFLAGS+= -D_MULTI_LIBM -D_POSIX_MODE -.endif - LIB= m WANTLINT= COMMON_SRCS = b_exp__D.c b_log__D.c b_tgamma.c \ @@ -105,31 +69,34 @@ COMMON_SRCS = b_exp__D.c b_log__D.c b_tgamma.c \ e_atan2.c e_atan2f.c e_atanh.c e_atanhf.c e_cosh.c e_coshf.c e_exp.c \ e_expf.c e_fmod.c e_fmodf.c e_hypot.c e_hypotf.c e_j0.c e_j0f.c \ e_j1.c e_j1f.c e_jn.c e_jnf.c e_lgamma_r.c e_lgammaf_r.c e_log.c \ - e_log10.c e_log10f.c e_logf.c e_pow.c e_powf.c e_rem_pio2.c \ + e_log10.c e_log10f.c e_log2.c e_log2f.c e_logf.c e_pow.c e_powf.c \ + e_rem_pio2.c \ e_rem_pio2f.c e_remainder.c e_remainderf.c e_scalb.c e_scalbf.c \ e_sinh.c e_sinhf.c e_sqrt.c e_sqrtf.c \ k_cos.c k_cosf.c k_rem_pio2.c k_rem_pio2f.c k_sin.c k_sinf.c \ - k_standard.c k_tan.c k_tanf.c \ + k_tan.c k_tanf.c \ s_lround.c s_lroundf.c s_llround.c s_llroundf.c \ - s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cbrt.c s_cbrtf.c s_ceil.c \ - s_ceilf.c s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_erf.c s_erff.c \ - s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabsf.c s_finite.c s_finitef.c \ + s_asinh.c s_asinhf.c s_atan.c s_atanf.c s_cabs.c s_cabsf.c s_cacos.c \ + s_cacosf.c s_cacosh.c s_cacoshf.c s_carg.c s_cargf.c s_casin.c \ + s_casinf.c s_casinh.c s_casinhf.c s_catan.c s_catanf.c s_catanh.c \ + s_catanhf.c s_cbrt.c s_cbrtf.c s_conj.c s_conjf.c s_ccos.c s_ccosf.c \ + s_ccosh.c s_ccoshf.c s_ceil.c \ + s_ceilf.c s_cexp.c s_cexpf.c s_cimag.c s_cimagf.c s_clog.c s_clogf.c \ + s_copysign.c s_copysignf.c s_cos.c s_cosf.c s_cpow.c s_cpowf.c \ + s_cproj.c s_cprojf.c s_creal.c s_crealf.c s_csin.c s_csinf.c s_csinh.c \ + s_csinhf.c s_csqrt.c s_csqrtf.c s_ctan.c s_ctanf.c s_ctanh.c \ + s_ctanhf.c s_erf.c s_erff.c s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c \ + s_fabsf.c s_fdim.c s_fmax.c s_fmaxf.c s_fmin.c s_fminf.c s_finite.c \ + s_finitef.c \ s_floor.c s_floorf.c s_frexpf.c s_ilogb.c s_ilogbf.c \ - s_ldexpf.c s_lib_version.c s_log1p.c \ + s_ldexpf.c s_log1p.c \ s_log1pf.c s_logb.c s_logbf.c s_llrint.c s_llrintf.c s_lrint.c \ - s_lrintf.c s_matherr.c s_modff.c s_nan.c \ + s_lrintf.c s_modff.c s_nan.c \ s_nextafter.c s_nextafterf.c s_remquo.c s_remquof.c s_rint.c \ s_rintf.c s_round.c s_roundf.c \ s_scalbn.c s_scalbnf.c s_signgam.c s_significand.c s_significandf.c \ - s_sin.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_trunc.c s_truncf.c \ - w_acos.c w_acosf.c w_acosh.c w_acoshf.c w_asin.c w_asinf.c w_atan2.c \ - w_atan2f.c w_atanh.c w_atanhf.c w_cabs.c w_cabsf.c w_cosh.c w_coshf.c \ - w_drem.c w_dremf.c w_exp.c w_expf.c w_fmod.c w_fmodf.c w_gamma.c \ - w_gamma_r.c w_gammaf.c w_gammaf_r.c w_hypot.c w_hypotf.c w_j0.c \ - w_j0f.c w_j1.c w_j1f.c w_jn.c w_jnf.c w_lgamma.c w_lgamma_r.c \ - w_lgammaf.c w_lgammaf_r.c w_log.c w_log10.c w_log10f.c w_logf.c \ - w_pow.c w_powf.c w_remainder.c w_remainderf.c w_scalb.c w_scalbf.c \ - w_sinh.c w_sinhf.c w_sqrt.c w_sqrtf.c + s_sin.c s_sinf.c s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_trunc.c \ + s_truncf.c w_drem.c w_dremf.c w_gamma.c w_gamma_r.c # math routines for non-IEEE architectures. NOIEEE_SRCS = n_asincos.c n_acosh.c n_asinh.c n_atan.c n_atanh.c n_cosh.c \ @@ -257,7 +224,7 @@ MLINKS+=trunc.3 truncf.3 #.endif #e_acos.o: -# cpp -D__LIBM_PRIVATE -D_USE_WRITE -D_MULTI_LIBM -D_POSIX_MODE \ +# cpp \ # /usr/src/lib/libm/arch/mc68881/e_acos.S | as -o e_acos.o diff --git a/lib/libm/arch/amd64/e_acos.S b/lib/libm/arch/amd64/e_acos.S index ecaa57f3c85..5b493c291e8 100644 --- a/lib/libm/arch/amd64/e_acos.S +++ b/lib/libm/arch/amd64/e_acos.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_acos.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_acos.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -9,7 +9,7 @@ #include "abi.h" /* acos = atan (sqrt(1 - x^2) / x) */ -ENTRY(__ieee754_acos) +ENTRY(acos) XMM_ONE_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_ONE /* x */ fld %st(0) diff --git a/lib/libm/arch/amd64/e_asin.S b/lib/libm/arch/amd64/e_asin.S index dc22db5dea2..3e337c88453 100644 --- a/lib/libm/arch/amd64/e_asin.S +++ b/lib/libm/arch/amd64/e_asin.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_asin.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_asin.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -9,7 +9,7 @@ #include "abi.h" /* asin = atan (x / sqrt(1 - x^2)) */ -ENTRY(__ieee754_asin) +ENTRY(asin) XMM_ONE_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_ONE /* x */ fld %st(0) diff --git a/lib/libm/arch/amd64/e_atan2.S b/lib/libm/arch/amd64/e_atan2.S index 11f5cf02af0..ac7c6bb627d 100644 --- a/lib/libm/arch/amd64/e_atan2.S +++ b/lib/libm/arch/amd64/e_atan2.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_atan2.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_atan2.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_atan2) +ENTRY(atan2) XMM_TWO_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_ONE fldl ARG_DOUBLE_TWO diff --git a/lib/libm/arch/amd64/e_atan2f.S b/lib/libm/arch/amd64/e_atan2f.S index c313367d836..77bd7cd4199 100644 --- a/lib/libm/arch/amd64/e_atan2f.S +++ b/lib/libm/arch/amd64/e_atan2f.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_atan2f.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_atan2f.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_atan2f) +ENTRY(atan2f) XMM_TWO_ARG_FLOAT_PROLOGUE flds ARG_FLOAT_ONE flds ARG_FLOAT_TWO diff --git a/lib/libm/arch/amd64/e_exp.S b/lib/libm/arch/amd64/e_exp.S index 5ae6516e991..101e3c74804 100644 --- a/lib/libm/arch/amd64/e_exp.S +++ b/lib/libm/arch/amd64/e_exp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_exp.S,v 1.4 2006/03/19 00:01:04 kettenis Exp $ */ +/* $OpenBSD: e_exp.S,v 1.5 2008/09/07 20:36:08 martynas Exp $ */ /* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */ /* @@ -41,7 +41,7 @@ #include "abi.h" /* e^x = 2^(x * log2(e)) */ -ENTRY(__ieee754_exp) +ENTRY(exp) XMM_ONE_ARG_DOUBLE_PROLOGUE /* * If x is +-Inf, then the subtraction would give Inf-Inf = NaN. diff --git a/lib/libm/arch/amd64/e_fmod.S b/lib/libm/arch/amd64/e_fmod.S index 4a4eb5d3f9f..71c8f9c3349 100644 --- a/lib/libm/arch/amd64/e_fmod.S +++ b/lib/libm/arch/amd64/e_fmod.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_fmod.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_fmod.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -9,7 +9,7 @@ #include "abi.h" -ENTRY(__ieee754_fmod) +ENTRY(fmod) XMM_TWO_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_TWO fldl ARG_DOUBLE_ONE diff --git a/lib/libm/arch/amd64/e_log.S b/lib/libm/arch/amd64/e_log.S index f92ec13f303..e0293b2c05d 100644 --- a/lib/libm/arch/amd64/e_log.S +++ b/lib/libm/arch/amd64/e_log.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_log.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_log) +ENTRY(log) XMM_ONE_ARG_DOUBLE_PROLOGUE fldln2 fldl ARG_DOUBLE_ONE diff --git a/lib/libm/arch/amd64/e_log10.S b/lib/libm/arch/amd64/e_log10.S index 4c7fdd0fba2..d0439b55b03 100644 --- a/lib/libm/arch/amd64/e_log10.S +++ b/lib/libm/arch/amd64/e_log10.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log10.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_log10.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_log10) +ENTRY(log10) XMM_ONE_ARG_DOUBLE_PROLOGUE fldlg2 fldl ARG_DOUBLE_ONE diff --git a/lib/libm/arch/amd64/e_remainder.S b/lib/libm/arch/amd64/e_remainder.S index a72ca5904f8..1971538cf05 100644 --- a/lib/libm/arch/amd64/e_remainder.S +++ b/lib/libm/arch/amd64/e_remainder.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_remainder.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_remainder.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_remainder) +ENTRY(remainder) XMM_TWO_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_TWO fldl ARG_DOUBLE_ONE diff --git a/lib/libm/arch/amd64/e_remainderf.S b/lib/libm/arch/amd64/e_remainderf.S index fe635ce83b2..c739332cb68 100644 --- a/lib/libm/arch/amd64/e_remainderf.S +++ b/lib/libm/arch/amd64/e_remainderf.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_remainderf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_remainderf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_remainderf) +ENTRY(remainderf) XMM_TWO_ARG_FLOAT_PROLOGUE flds ARG_FLOAT_TWO flds ARG_FLOAT_ONE diff --git a/lib/libm/arch/amd64/e_scalb.S b/lib/libm/arch/amd64/e_scalb.S index 1f05561ada9..ac5549999d2 100644 --- a/lib/libm/arch/amd64/e_scalb.S +++ b/lib/libm/arch/amd64/e_scalb.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_scalb.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_scalb.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -8,7 +8,7 @@ #include "abi.h" -ENTRY(__ieee754_scalb) +ENTRY(scalb) XMM_TWO_ARG_DOUBLE_PROLOGUE fldl ARG_DOUBLE_TWO fldl ARG_DOUBLE_ONE diff --git a/lib/libm/arch/amd64/e_sqrt.S b/lib/libm/arch/amd64/e_sqrt.S index 6b8a722a144..65f26380f0e 100644 --- a/lib/libm/arch/amd64/e_sqrt.S +++ b/lib/libm/arch/amd64/e_sqrt.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sqrt.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_sqrt.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_sqrt) +ENTRY(sqrt) #ifdef __i386__ fldl 4(%esp) fsqrt diff --git a/lib/libm/arch/amd64/e_sqrtf.S b/lib/libm/arch/amd64/e_sqrtf.S index f49826a0ced..599358f70f8 100644 --- a/lib/libm/arch/amd64/e_sqrtf.S +++ b/lib/libm/arch/amd64/e_sqrtf.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sqrtf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_sqrtf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@NetBSD.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_sqrtf) +ENTRY(sqrtf) #ifdef __i386__ flds 4(%esp) fsqrt diff --git a/lib/libm/arch/hppa/e_remainder.c b/lib/libm/arch/hppa/e_remainder.c index 15db821d42c..0098c39c911 100644 --- a/lib/libm/arch/hppa/e_remainder.c +++ b/lib/libm/arch/hppa/e_remainder.c @@ -3,13 +3,13 @@ */ #if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: e_remainder.c,v 1.1 2002/05/22 21:34:56 mickey Exp $"; +static char rcsid[] = "$OpenBSD: e_remainder.c,v 1.2 2008/09/07 20:36:08 martynas Exp $"; #endif #include "math.h" double -__ieee754_remainder(double x, double p) +remainder(double x, double p) { __asm__ __volatile__("frem,dbl %0,%1,%0" : "+f" (x) : "f" (p)); diff --git a/lib/libm/arch/hppa/e_remainderf.c b/lib/libm/arch/hppa/e_remainderf.c index b39314978b7..87e0871ec27 100644 --- a/lib/libm/arch/hppa/e_remainderf.c +++ b/lib/libm/arch/hppa/e_remainderf.c @@ -3,13 +3,13 @@ */ #if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: e_remainderf.c,v 1.2 2004/05/22 23:36:27 mickey Exp $"; +static char rcsid[] = "$OpenBSD: e_remainderf.c,v 1.3 2008/09/07 20:36:08 martynas Exp $"; #endif #include "math.h" float -__ieee754_remainderf(float x, float p) +remainderf(float x, float p) { __asm__ __volatile__("frem,sgl %0,%1,%0" : "+f" (x) : "f" (p)); diff --git a/lib/libm/arch/hppa/e_sqrt.c b/lib/libm/arch/hppa/e_sqrt.c index 1345f287269..5c2663a6934 100644 --- a/lib/libm/arch/hppa/e_sqrt.c +++ b/lib/libm/arch/hppa/e_sqrt.c @@ -3,13 +3,13 @@ */ #if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: e_sqrt.c,v 1.1 2002/05/22 20:55:56 mickey Exp $"; +static char rcsid[] = "$OpenBSD: e_sqrt.c,v 1.2 2008/09/07 20:36:08 martynas Exp $"; #endif #include "math.h" double -__ieee754_sqrt(double x) +sqrt(double x) { __asm__ __volatile__ ("fsqrt,dbl %0, %0" : "+f" (x)); return (x); diff --git a/lib/libm/arch/hppa/e_sqrtf.c b/lib/libm/arch/hppa/e_sqrtf.c index 81ba8ba38f4..c5fff115f13 100644 --- a/lib/libm/arch/hppa/e_sqrtf.c +++ b/lib/libm/arch/hppa/e_sqrtf.c @@ -3,13 +3,13 @@ */ #if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: e_sqrtf.c,v 1.1 2002/05/22 20:55:56 mickey Exp $"; +static char rcsid[] = "$OpenBSD: e_sqrtf.c,v 1.2 2008/09/07 20:36:08 martynas Exp $"; #endif #include "math.h" float -__ieee754_sqrtf(float x) +sqrtf(float x) { __asm__ __volatile__ ("fsqrt,sgl %0, %0" : "+f" (x)); return (x); diff --git a/lib/libm/arch/i387/e_acos.S b/lib/libm/arch/i387/e_acos.S index 154cb6f6621..d85aaad3e26 100644 --- a/lib/libm/arch/i387/e_acos.S +++ b/lib/libm/arch/i387/e_acos.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_acos.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_acos.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -7,7 +7,7 @@ #include <machine/asm.h> /* acos = atan (sqrt(1 - x^2) / x) */ -ENTRY(__ieee754_acos) +ENTRY(acos) fldl 4(%esp) /* x */ fst %st(1) fmul %st(0) /* x^2 */ diff --git a/lib/libm/arch/i387/e_asin.S b/lib/libm/arch/i387/e_asin.S index 0692cf3598d..bb3d0f95bfa 100644 --- a/lib/libm/arch/i387/e_asin.S +++ b/lib/libm/arch/i387/e_asin.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_asin.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_asin.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -7,7 +7,7 @@ #include <machine/asm.h> /* asin = atan (x / sqrt(1 - x^2)) */ -ENTRY(__ieee754_asin) +ENTRY(asin) fldl 4(%esp) /* x */ fst %st(1) fmul %st(0) /* x^2 */ diff --git a/lib/libm/arch/i387/e_atan2.S b/lib/libm/arch/i387/e_atan2.S index d36838a358f..9057bd97eea 100644 --- a/lib/libm/arch/i387/e_atan2.S +++ b/lib/libm/arch/i387/e_atan2.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_atan2.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_atan2.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_atan2) +ENTRY(atan2) fldl 4(%esp) fldl 12(%esp) fpatan diff --git a/lib/libm/arch/i387/e_atan2f.S b/lib/libm/arch/i387/e_atan2f.S index 747f30832ac..734d101c977 100644 --- a/lib/libm/arch/i387/e_atan2f.S +++ b/lib/libm/arch/i387/e_atan2f.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_atan2f.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_atan2f.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_atan2f) +ENTRY(atan2f) flds 4(%esp) flds 8(%esp) fpatan diff --git a/lib/libm/arch/i387/e_exp.S b/lib/libm/arch/i387/e_exp.S index 3880dbc4311..2d085df48d9 100644 --- a/lib/libm/arch/i387/e_exp.S +++ b/lib/libm/arch/i387/e_exp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_exp.S,v 1.7 2006/03/18 23:56:14 kettenis Exp $ */ +/* $OpenBSD: e_exp.S,v 1.8 2008/09/07 20:36:08 martynas Exp $ */ /* $NetBSD: e_exp.S,v 1.12 2002/02/27 16:32:46 christos Exp $ */ /* @@ -39,7 +39,7 @@ #include <machine/asm.h> /* e^x = 2^(x * log2(e)) */ -ENTRY(__ieee754_exp) +ENTRY(exp) /* * If x is +-Inf, then the subtraction would give Inf-Inf = NaN. * Avoid this. Also avoid it if x is NaN for convenience. diff --git a/lib/libm/arch/i387/e_fmod.S b/lib/libm/arch/i387/e_fmod.S index c4e6790e9e3..daa1dfa34a7 100644 --- a/lib/libm/arch/i387/e_fmod.S +++ b/lib/libm/arch/i387/e_fmod.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_fmod.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_fmod.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_fmod) +ENTRY(fmod) fldl 12(%esp) fldl 4(%esp) 1: fprem diff --git a/lib/libm/arch/i387/e_log.S b/lib/libm/arch/i387/e_log.S index 2b50032caa3..54e9423f03c 100644 --- a/lib/libm/arch/i387/e_log.S +++ b/lib/libm/arch/i387/e_log.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_log.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_log) +ENTRY(log) fldln2 fldl 4(%esp) fyl2x diff --git a/lib/libm/arch/i387/e_log10.S b/lib/libm/arch/i387/e_log10.S index 71cb29b5a66..4045a56ee6a 100644 --- a/lib/libm/arch/i387/e_log10.S +++ b/lib/libm/arch/i387/e_log10.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log10.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_log10.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_log10) +ENTRY(log10) fldlg2 fldl 4(%esp) fyl2x diff --git a/lib/libm/arch/i387/e_remainder.S b/lib/libm/arch/i387/e_remainder.S index 86f7d761f3d..a9f31df1b17 100644 --- a/lib/libm/arch/i387/e_remainder.S +++ b/lib/libm/arch/i387/e_remainder.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_remainder.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_remainder.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_remainder) +ENTRY(remainder) fldl 12(%esp) fldl 4(%esp) 1: fprem1 diff --git a/lib/libm/arch/i387/e_remainderf.S b/lib/libm/arch/i387/e_remainderf.S index 39a09370407..dc92ee23dfd 100644 --- a/lib/libm/arch/i387/e_remainderf.S +++ b/lib/libm/arch/i387/e_remainderf.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_remainderf.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_remainderf.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_remainderf) +ENTRY(remainderf) flds 8(%esp) flds 4(%esp) 1: fprem1 diff --git a/lib/libm/arch/i387/e_scalb.S b/lib/libm/arch/i387/e_scalb.S index 65ab69e39de..b515d76e713 100644 --- a/lib/libm/arch/i387/e_scalb.S +++ b/lib/libm/arch/i387/e_scalb.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_scalb.S,v 1.3 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_scalb.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_scalb) +ENTRY(scalb) fldl 12(%esp) fldl 4(%esp) fscale diff --git a/lib/libm/arch/i387/e_sqrt.S b/lib/libm/arch/i387/e_sqrt.S index aa5402f5e01..9e9e5854679 100644 --- a/lib/libm/arch/i387/e_sqrt.S +++ b/lib/libm/arch/i387/e_sqrt.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sqrt.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_sqrt.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_sqrt) +ENTRY(sqrt) fldl 4(%esp) fsqrt ret diff --git a/lib/libm/arch/i387/e_sqrtf.S b/lib/libm/arch/i387/e_sqrtf.S index 8de86dffe38..f6e30ef258f 100644 --- a/lib/libm/arch/i387/e_sqrtf.S +++ b/lib/libm/arch/i387/e_sqrtf.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sqrtf.S,v 1.2 2005/08/02 11:17:31 espie Exp $ */ +/* $OpenBSD: e_sqrtf.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_sqrtf) +ENTRY(sqrtf) flds 4(%esp) fsqrt ret diff --git a/lib/libm/arch/mc68881/e_acos.S b/lib/libm/arch/mc68881/e_acos.S index 6920f26124d..b37d54ba829 100644 --- a/lib/libm/arch/mc68881/e_acos.S +++ b/lib/libm/arch/mc68881/e_acos.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_acos.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_acos.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_acos) +ENTRY(acos) facosd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_asin.S b/lib/libm/arch/mc68881/e_asin.S index ea94bc0b637..38d8910cd1f 100644 --- a/lib/libm/arch/mc68881/e_asin.S +++ b/lib/libm/arch/mc68881/e_asin.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_asin.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_asin.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_asin) +ENTRY(asin) fasind sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_atanh.S b/lib/libm/arch/mc68881/e_atanh.S index ab74bfe7534..4084b0b3bff 100644 --- a/lib/libm/arch/mc68881/e_atanh.S +++ b/lib/libm/arch/mc68881/e_atanh.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_atanh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_atanh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_atanh) +ENTRY(atanh) fatanhd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_cosh.S b/lib/libm/arch/mc68881/e_cosh.S index 1b2ca0506ff..b2cf85b7cdb 100644 --- a/lib/libm/arch/mc68881/e_cosh.S +++ b/lib/libm/arch/mc68881/e_cosh.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_cosh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_cosh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_cosh) +ENTRY(cosh) fcoshd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_exp.S b/lib/libm/arch/mc68881/e_exp.S index 39920d4b480..3fd33ea1791 100644 --- a/lib/libm/arch/mc68881/e_exp.S +++ b/lib/libm/arch/mc68881/e_exp.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_exp.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_exp.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_exp) +ENTRY(exp) fetoxd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_log.S b/lib/libm/arch/mc68881/e_log.S index d8b03499e8a..ecca1c78db9 100644 --- a/lib/libm/arch/mc68881/e_log.S +++ b/lib/libm/arch/mc68881/e_log.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_log.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_log) +ENTRY(log) flognd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_log10.S b/lib/libm/arch/mc68881/e_log10.S index d057e409f70..9be1b63c0b5 100644 --- a/lib/libm/arch/mc68881/e_log10.S +++ b/lib/libm/arch/mc68881/e_log10.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_log10.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_log10.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_log10) +ENTRY(log10) flog10d sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_remainder.S b/lib/libm/arch/mc68881/e_remainder.S index d4433fe858a..87dd01cfc63 100644 --- a/lib/libm/arch/mc68881/e_remainder.S +++ b/lib/libm/arch/mc68881/e_remainder.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_remainder.S,v 1.2 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_remainder.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_remainder) +ENTRY(remainder) fmoved sp@(4),fp0 fremd sp@(12),fp0 fmoved fp0,sp@- diff --git a/lib/libm/arch/mc68881/e_scalb.S b/lib/libm/arch/mc68881/e_scalb.S index 724a6996bb4..f133e0621c1 100644 --- a/lib/libm/arch/mc68881/e_scalb.S +++ b/lib/libm/arch/mc68881/e_scalb.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_scalb.S,v 1.2 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_scalb.S,v 1.3 2008/09/07 20:36:08 martynas Exp $ */ /* * Written by J.T. Conklin <jtc@netbsd.org>. * Public domain. @@ -6,7 +6,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_scalb) +ENTRY(scalb) fmoved sp@(4),fp0 fbeq Ldone fscaled sp@(12),fp0 diff --git a/lib/libm/arch/mc68881/e_sinh.S b/lib/libm/arch/mc68881/e_sinh.S index 60a21c47c69..10e35b20882 100644 --- a/lib/libm/arch/mc68881/e_sinh.S +++ b/lib/libm/arch/mc68881/e_sinh.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sinh.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_sinh.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -34,7 +34,7 @@ #include <machine/asm.h> -ENTRY(__ieee754_sinh) +ENTRY(sinh) fsinhd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/arch/mc68881/e_sqrt.S b/lib/libm/arch/mc68881/e_sqrt.S index 0639e5fcf7e..df4f21f01e1 100644 --- a/lib/libm/arch/mc68881/e_sqrt.S +++ b/lib/libm/arch/mc68881/e_sqrt.S @@ -1,4 +1,4 @@ -/* $OpenBSD: e_sqrt.S,v 1.3 2005/08/02 11:17:32 espie Exp $ */ +/* $OpenBSD: e_sqrt.S,v 1.4 2008/09/07 20:36:08 martynas Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. @@ -40,7 +40,7 @@ * to the rounding mode. */ -ENTRY(__ieee754_sqrt) +ENTRY(sqrt) fsqrtd sp@(4),fp0 fmoved fp0,sp@- movel sp@+,d0 diff --git a/lib/libm/shlib_version b/lib/libm/shlib_version index 012c14171d3..d9961ea9fef 100644 --- a/lib/libm/shlib_version +++ b/lib/libm/shlib_version @@ -1,2 +1,2 @@ -major=3 +major=4 minor=0 diff --git a/lib/libm/src/e_acos.c b/lib/libm/src/e_acos.c index a5301808768..2ae24586cc1 100644 --- a/lib/libm/src/e_acos.c +++ b/lib/libm/src/e_acos.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $"; #endif -/* __ieee754_acos(x) +/* acos(x) * Method : * acos(x) = pi/2 - asin(x) * acos(-x) = pi/2 + asin(x) @@ -35,7 +35,7 @@ static char rcsid[] = "$NetBSD: e_acos.c,v 1.9 1995/05/12 04:57:13 jtc Exp $"; * if x is NaN, return x itself; * if |x|>1, return NaN with invalid signal. * - * Function needed: __ieee754_sqrt + * Function needed: sqrt */ #include "math.h" @@ -58,7 +58,7 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ double -__ieee754_acos(double x) +acos(double x) { double z,p,q,r,w,s,c,df; int32_t hx,ix; @@ -84,13 +84,13 @@ __ieee754_acos(double x) z = (one+x)*0.5; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - s = __ieee754_sqrt(z); + s = sqrt(z); r = p/q; w = r*s-pio2_lo; return pi - 2.0*(s+w); } else { /* x > 0.5 */ z = (one-x)*0.5; - s = __ieee754_sqrt(z); + s = sqrt(z); df = s; SET_LOW_WORD(df,0); c = (z-df*df)/(s+df); diff --git a/lib/libm/src/e_acosf.c b/lib/libm/src/e_acosf.c index 5407842186c..57f42b18f8f 100644 --- a/lib/libm/src/e_acosf.c +++ b/lib/libm/src/e_acosf.c @@ -37,7 +37,7 @@ qS3 = -6.8828397989e-01, /* 0xbf303361 */ qS4 = 7.7038154006e-02; /* 0x3d9dc62e */ float -__ieee754_acosf(float x) +acosf(float x) { float z,p,q,r,w,s,c,df; int32_t hx,ix; @@ -60,14 +60,14 @@ __ieee754_acosf(float x) z = (one+x)*(float)0.5; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - s = __ieee754_sqrtf(z); + s = sqrtf(z); r = p/q; w = r*s-pio2_lo; return pi - (float)2.0*(s+w); } else { /* x > 0.5 */ int32_t idf; z = (one-x)*(float)0.5; - s = __ieee754_sqrtf(z); + s = sqrtf(z); df = s; GET_FLOAT_WORD(idf,df); SET_FLOAT_WORD(df,idf&0xfffff000); diff --git a/lib/libm/src/e_acosh.c b/lib/libm/src/e_acosh.c index fbfb65e09d0..273b93d02a6 100644 --- a/lib/libm/src/e_acosh.c +++ b/lib/libm/src/e_acosh.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_acosh.c,v 1.9 1995/05/12 04:57:18 jtc Exp $"; #endif -/* __ieee754_acosh(x) +/* acosh(x) * Method : * Based on * acosh(x) = log [ x + sqrt(x*x-1) ] @@ -36,7 +36,7 @@ one = 1.0, ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ double -__ieee754_acosh(double x) +acosh(double x) { double t; int32_t hx; @@ -48,12 +48,12 @@ __ieee754_acosh(double x) if(hx >=0x7ff00000) { /* x is inf of NaN */ return x+x; } else - return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ + return log(x)+ln2; /* acosh(huge)=log(2x) */ } else if(((hx-0x3ff00000)|lx)==0) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t=x*x; - return __ieee754_log(2.0*x-one/(x+__ieee754_sqrt(t-one))); + return log(2.0*x-one/(x+sqrt(t-one))); } else { /* 1<x<2 */ t = x-one; return log1p(t+sqrt(2.0*t+t*t)); diff --git a/lib/libm/src/e_acoshf.c b/lib/libm/src/e_acoshf.c index 6e3b1e96870..515d33daf0c 100644 --- a/lib/libm/src/e_acoshf.c +++ b/lib/libm/src/e_acoshf.c @@ -25,7 +25,7 @@ one = 1.0, ln2 = 6.9314718246e-01; /* 0x3f317218 */ float -__ieee754_acoshf(float x) +acoshf(float x) { float t; int32_t hx; @@ -36,12 +36,12 @@ __ieee754_acoshf(float x) if(hx >=0x7f800000) { /* x is inf of NaN */ return x+x; } else - return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ + return logf(x)+ln2; /* acosh(huge)=log(2x) */ } else if (hx==0x3f800000) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t=x*x; - return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one))); + return logf((float)2.0*x-one/(x+sqrtf(t-one))); } else { /* 1<x<2 */ t = x-one; return log1pf(t+sqrtf((float)2.0*t+t*t)); diff --git a/lib/libm/src/e_asin.c b/lib/libm/src/e_asin.c index 0d358012280..4c732971e40 100644 --- a/lib/libm/src/e_asin.c +++ b/lib/libm/src/e_asin.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_asin.c,v 1.9 1995/05/12 04:57:22 jtc Exp $"; #endif -/* __ieee754_asin(x) +/* asin(x) * Method : * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ... * we approximate asin(x) on [0,0.5] by @@ -67,7 +67,7 @@ qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ double -__ieee754_asin(double x) +asin(double x) { double t,w,p,q,c,r,s; int32_t hx,ix; @@ -95,7 +95,7 @@ __ieee754_asin(double x) t = w*0.5; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); - s = __ieee754_sqrt(t); + s = sqrt(t); if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ w = p/q; t = pio2_hi-(2.0*(s+s*w)-pio2_lo); diff --git a/lib/libm/src/e_asinf.c b/lib/libm/src/e_asinf.c index f4e780847ed..3f70199fbc9 100644 --- a/lib/libm/src/e_asinf.c +++ b/lib/libm/src/e_asinf.c @@ -39,7 +39,7 @@ qS3 = -6.8828397989e-01, /* 0xbf303361 */ qS4 = 7.7038154006e-02; /* 0x3d9dc62e */ float -__ieee754_asinf(float x) +asinf(float x) { float t,w,p,q,c,r,s; int32_t hx,ix; @@ -65,7 +65,7 @@ __ieee754_asinf(float x) t = w*(float)0.5; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); - s = __ieee754_sqrtf(t); + s = sqrtf(t); if(ix>=0x3F79999A) { /* if |x| > 0.975 */ w = p/q; t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo); diff --git a/lib/libm/src/e_atan2.c b/lib/libm/src/e_atan2.c index d469450efe0..f8a0330dcb8 100644 --- a/lib/libm/src/e_atan2.c +++ b/lib/libm/src/e_atan2.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_atan2.c,v 1.8 1995/05/10 20:44:51 jtc Exp $"; #endif -/* __ieee754_atan2(y,x) +/* atan2(y,x) * Method : * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). * 2. Reduce x to positive by (if x and y are unexceptional): @@ -53,7 +53,7 @@ pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ double -__ieee754_atan2(double y, double x) +atan2(double y, double x) { double z; int32_t k,m,hx,hy,ix,iy; diff --git a/lib/libm/src/e_atan2f.c b/lib/libm/src/e_atan2f.c index ead3b133972..0855bd4ffb5 100644 --- a/lib/libm/src/e_atan2f.c +++ b/lib/libm/src/e_atan2f.c @@ -29,7 +29,7 @@ pi = 3.1415925026e+00, /* 0x40490fda */ pi_lo = 1.5099578832e-07; /* 0x34222168 */ float -__ieee754_atan2f(float y, float x) +atan2f(float y, float x) { float z; int32_t k,m,hx,hy,ix,iy; diff --git a/lib/libm/src/e_atanh.c b/lib/libm/src/e_atanh.c index fd9d952b61f..1cd468b8e56 100644 --- a/lib/libm/src/e_atanh.c +++ b/lib/libm/src/e_atanh.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_atanh.c,v 1.8 1995/05/10 20:44:55 jtc Exp $"; #endif -/* __ieee754_atanh(x) +/* atanh(x) * Method : * 1.Reduced x to positive by atanh(-x) = -atanh(x) * 2.For x>=0.5 @@ -39,7 +39,7 @@ static const double one = 1.0, huge = 1e300; static const double zero = 0.0; double -__ieee754_atanh(double x) +atanh(double x) { double t; int32_t hx,ix; diff --git a/lib/libm/src/e_atanhf.c b/lib/libm/src/e_atanhf.c index 8d912239224..40322c2cf0c 100644 --- a/lib/libm/src/e_atanhf.c +++ b/lib/libm/src/e_atanhf.c @@ -24,7 +24,7 @@ static const float one = 1.0, huge = 1e30; static const float zero = 0.0; float -__ieee754_atanhf(float x) +atanhf(float x) { float t; int32_t hx,ix; diff --git a/lib/libm/src/e_cosh.c b/lib/libm/src/e_cosh.c index 4d7b61bfdc9..afad33162af 100644 --- a/lib/libm/src/e_cosh.c +++ b/lib/libm/src/e_cosh.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $"; #endif -/* __ieee754_cosh(x) +/* cosh(x) * Method : * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 * 1. Replace x by |x| (cosh(x) = cosh(-x)). @@ -41,7 +41,7 @@ static char rcsid[] = "$NetBSD: e_cosh.c,v 1.7 1995/05/10 20:44:58 jtc Exp $"; static const double one = 1.0, half=0.5, huge = 1.0e300; double -__ieee754_cosh(double x) +cosh(double x) { double t,w; int32_t ix; @@ -64,18 +64,18 @@ __ieee754_cosh(double x) /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ if (ix < 0x40360000) { - t = __ieee754_exp(fabs(x)); + t = exp(fabs(x)); return half*t+half/t; } /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ - if (ix < 0x40862E42) return half*__ieee754_exp(fabs(x)); + if (ix < 0x40862E42) return half*exp(fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ GET_LOW_WORD(lx,x); if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { - w = __ieee754_exp(half*fabs(x)); + w = exp(half*fabs(x)); t = half*w; return t*w; } diff --git a/lib/libm/src/e_coshf.c b/lib/libm/src/e_coshf.c index ae52f14d7a3..29eb56cfd4e 100644 --- a/lib/libm/src/e_coshf.c +++ b/lib/libm/src/e_coshf.c @@ -24,7 +24,7 @@ static const volatile float huge = 1.0e30; static const float one = 1.0, half=0.5; float -__ieee754_coshf(float x) +coshf(float x) { float t,w; int32_t ix; @@ -45,16 +45,16 @@ __ieee754_coshf(float x) /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ if (ix < 0x41b00000) { - t = __ieee754_expf(fabsf(x)); + t = expf(fabsf(x)); return half*t+half/t; } /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ - if (ix < 0x42b17180) return half*__ieee754_expf(fabsf(x)); + if (ix < 0x42b17180) return half*expf(fabsf(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix<=0x42b2d4fc) { - w = __ieee754_expf(half*fabsf(x)); + w = expf(half*fabsf(x)); t = half*w; return t*w; } diff --git a/lib/libm/src/e_exp.c b/lib/libm/src/e_exp.c index c9ecdecdc04..aef00ba006d 100644 --- a/lib/libm/src/e_exp.c +++ b/lib/libm/src/e_exp.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_exp.c,v 1.8 1995/05/10 20:45:03 jtc Exp $"; #endif -/* __ieee754_exp(x) +/* exp(x) * Returns the exponential of x. * * Method @@ -100,7 +100,7 @@ P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ double -__ieee754_exp(double x) /* default IEEE double exp */ +exp(double x) /* default IEEE double exp */ { double y,hi,lo,c,t; int32_t k,xsb; diff --git a/lib/libm/src/e_expf.c b/lib/libm/src/e_expf.c index 2457f286bb9..ac0fc40df09 100644 --- a/lib/libm/src/e_expf.c +++ b/lib/libm/src/e_expf.c @@ -40,7 +40,7 @@ P4 = -1.6533901999e-06, /* 0xb5ddea0e */ P5 = 4.1381369442e-08; /* 0x3331bb4c */ float -__ieee754_expf(float x) /* default IEEE double exp */ +expf(float x) /* default IEEE double exp */ { float y,hi,lo,c,t; int32_t k,xsb; diff --git a/lib/libm/src/e_fmod.c b/lib/libm/src/e_fmod.c index 377dee8e569..1a85f8295c1 100644 --- a/lib/libm/src/e_fmod.c +++ b/lib/libm/src/e_fmod.c @@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $"; #endif /* - * __ieee754_fmod(x,y) + * fmod(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract */ @@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: e_fmod.c,v 1.8 1995/05/10 20:45:07 jtc Exp $"; static const double one = 1.0, Zero[] = {0.0, -0.0,}; double -__ieee754_fmod(double x, double y) +fmod(double x, double y) { int32_t n,hx,hy,hz,ix,iy,sx,i; u_int32_t lx,ly,lz; diff --git a/lib/libm/src/e_fmodf.c b/lib/libm/src/e_fmodf.c index 5313a0efdf9..0bb8d172925 100644 --- a/lib/libm/src/e_fmodf.c +++ b/lib/libm/src/e_fmodf.c @@ -18,7 +18,7 @@ static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4 1995/05/10 20:45:10 jtc Exp $"; #endif /* - * __ieee754_fmodf(x,y) + * fmodf(x,y) * Return x mod y in exact arithmetic * Method: shift and subtract */ @@ -29,7 +29,7 @@ static char rcsid[] = "$NetBSD: e_fmodf.c,v 1.4 1995/05/10 20:45:10 jtc Exp $"; static const float one = 1.0, Zero[] = {0.0, -0.0,}; float -__ieee754_fmodf(float x, float y) +fmodf(float x, float y) { int32_t n,hx,hy,hz,ix,iy,sx,i; diff --git a/lib/libm/src/e_hypot.c b/lib/libm/src/e_hypot.c index 6dc49042b63..23cf67f766d 100644 --- a/lib/libm/src/e_hypot.c +++ b/lib/libm/src/e_hypot.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $"; #endif -/* __ieee754_hypot(x,y) +/* hypot(x,y) * * Method : * If (assume round-to-nearest) z=x*x+y*y @@ -50,7 +50,7 @@ static char rcsid[] = "$NetBSD: e_hypot.c,v 1.9 1995/05/12 04:57:27 jtc Exp $"; #include "math_private.h" double -__ieee754_hypot(double x, double y) +hypot(double x, double y) { double a=x,b=y,t1,t2,yy1,y2,w; int32_t j,k,ha,hb; @@ -103,7 +103,7 @@ __ieee754_hypot(double x, double y) t1 = 0; SET_HIGH_WORD(t1,ha); t2 = a-t1; - w = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); + w = sqrt(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; yy1 = 0; @@ -112,7 +112,7 @@ __ieee754_hypot(double x, double y) t1 = 0; SET_HIGH_WORD(t1,ha+0x00100000); t2 = a - t1; - w = __ieee754_sqrt(t1*yy1-(w*(-w)-(t1*y2+t2*b))); + w = sqrt(t1*yy1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t high; diff --git a/lib/libm/src/e_hypotf.c b/lib/libm/src/e_hypotf.c index db781f5dfdc..863899f2ef6 100644 --- a/lib/libm/src/e_hypotf.c +++ b/lib/libm/src/e_hypotf.c @@ -21,7 +21,7 @@ static char rcsid[] = "$NetBSD: e_hypotf.c,v 1.5 1995/05/12 04:57:30 jtc Exp $"; #include "math_private.h" float -__ieee754_hypotf(float x, float y) +hypotf(float x, float y) { float a=x,b=y,t1,t2,yy1,y2,w; int32_t j,k,ha,hb; @@ -67,14 +67,14 @@ __ieee754_hypotf(float x, float y) if (w>b) { SET_FLOAT_WORD(t1,ha&0xfffff000); t2 = a-t1; - w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); + w = sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; SET_FLOAT_WORD(yy1,hb&0xfffff000); y2 = b - yy1; SET_FLOAT_WORD(t1,ha+0x00800000); t2 = a - t1; - w = __ieee754_sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b))); + w = sqrtf(t1*yy1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); diff --git a/lib/libm/src/e_j0.c b/lib/libm/src/e_j0.c index d49297ca8f3..ef34cb7887b 100644 --- a/lib/libm/src/e_j0.c +++ b/lib/libm/src/e_j0.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_j0.c,v 1.8 1995/05/10 20:45:23 jtc Exp $"; #endif -/* __ieee754_j0(x), __ieee754_y0(x) +/* j0(x), y0(x) * Bessel function of the first and second kinds of order zero. * Method -- j0(x): * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... @@ -82,7 +82,7 @@ S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ static const double zero = 0.0; double -__ieee754_j0(double x) +j0(double x) { double z, s,c,ss,cc,r,u,v; int32_t hx,ix; @@ -143,7 +143,7 @@ v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ double -__ieee754_y0(double x) +y0(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; @@ -187,12 +187,12 @@ __ieee754_y0(double x) return z; } if(ix<=0x3e400000) { /* x < 2**-27 */ - return(u00 + tpi*__ieee754_log(x)); + return(u00 + tpi*log(x)); } z = x*x; u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); - return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); + return(u/v + tpi*(j0(x)*log(x))); } /* The asymptotic expansions of pzero is diff --git a/lib/libm/src/e_j0f.c b/lib/libm/src/e_j0f.c index 02471711017..f5000adf5b6 100644 --- a/lib/libm/src/e_j0f.c +++ b/lib/libm/src/e_j0f.c @@ -40,7 +40,7 @@ S04 = 1.1661400734e-09; /* 0x30a045e8 */ static const float zero = 0.0; float -__ieee754_j0f(float x) +j0f(float x) { float z, s,c,ss,cc,r,u,v; int32_t hx,ix; @@ -101,7 +101,7 @@ v03 = 2.5915085189e-07, /* 0x348b216c */ v04 = 4.4111031494e-10; /* 0x2ff280c2 */ float -__ieee754_y0f(float x) +y0f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; @@ -145,12 +145,12 @@ __ieee754_y0f(float x) return z; } if(ix<=0x32000000) { /* x < 2**-27 */ - return(u00 + tpi*__ieee754_logf(x)); + return(u00 + tpi*logf(x)); } z = x*x; u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); - return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x))); + return(u/v + tpi*(j0f(x)*logf(x))); } /* The asymptotic expansions of pzero is diff --git a/lib/libm/src/e_j1.c b/lib/libm/src/e_j1.c index 372767ad582..3a783c80f08 100644 --- a/lib/libm/src/e_j1.c +++ b/lib/libm/src/e_j1.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_j1.c,v 1.8 1995/05/10 20:45:27 jtc Exp $"; #endif -/* __ieee754_j1(x), __ieee754_y1(x) +/* j1(x), y1(x) * Bessel function of the first and second kinds of order zero. * Method -- j1(x): * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... @@ -83,7 +83,7 @@ s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ static const double zero = 0.0; double -__ieee754_j1(double x) +j1(double x) { double z, s,c,ss,cc,r,u,v,y; int32_t hx,ix; @@ -140,7 +140,7 @@ static const double V0[5] = { }; double -__ieee754_y1(double x) +y1(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; @@ -185,7 +185,7 @@ __ieee754_y1(double x) z = x*x; u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); - return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); + return(x*(u/v) + tpi*(j1(x)*log(x)-one/x)); } /* For x >= 8, the asymptotic expansions of pone is diff --git a/lib/libm/src/e_j1f.c b/lib/libm/src/e_j1f.c index bccc8f68ccc..62b34072ea8 100644 --- a/lib/libm/src/e_j1f.c +++ b/lib/libm/src/e_j1f.c @@ -41,7 +41,7 @@ s05 = 1.2354227016e-11; /* 0x2d59567e */ static const float zero = 0.0; float -__ieee754_j1f(float x) +j1f(float x) { float z, s,c,ss,cc,r,u,v,y; int32_t hx,ix; @@ -98,7 +98,7 @@ static const float V0[5] = { }; float -__ieee754_y1f(float x) +y1f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; @@ -143,7 +143,7 @@ __ieee754_y1f(float x) z = x*x; u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); - return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x)); + return(x*(u/v) + tpi*(j1f(x)*logf(x)-one/x)); } /* For x >= 8, the asymptotic expansions of pone is diff --git a/lib/libm/src/e_jn.c b/lib/libm/src/e_jn.c index ada373aa6b4..f22231a8e97 100644 --- a/lib/libm/src/e_jn.c +++ b/lib/libm/src/e_jn.c @@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_jn.c,v 1.9 1995/05/10 20:45:34 jtc Exp $"; #endif /* - * __ieee754_jn(n, x), __ieee754_yn(n, x) + * jn(n, x), yn(n, x) * floating point Bessel's function of the 1st and 2nd kind * of order n * @@ -51,7 +51,7 @@ one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ static const double zero = 0.00000000000000000000e+00; double -__ieee754_jn(int n, double x) +jn(int n, double x) { int32_t i,hx,ix,lx, sgn; double a, b, temp, di; @@ -69,8 +69,8 @@ __ieee754_jn(int n, double x) x = -x; hx ^= 0x80000000; } - if(n==0) return(__ieee754_j0(x)); - if(n==1) return(__ieee754_j1(x)); + if(n==0) return(j0(x)); + if(n==1) return(j1(x)); sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ x = fabs(x); if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */ @@ -99,8 +99,8 @@ __ieee754_jn(int n, double x) } b = invsqrtpi*temp/sqrt(x); } else { - a = __ieee754_j0(x); - b = __ieee754_j1(x); + a = j0(x); + b = j1(x); for(i=1;i<n;i++){ temp = b; b = b*((double)(i+i)/x) - a; /* avoid underflow */ @@ -176,7 +176,7 @@ __ieee754_jn(int n, double x) */ tmp = n; v = two/x; - tmp = tmp*__ieee754_log(fabs(v*tmp)); + tmp = tmp*log(fabs(v*tmp)); if(tmp<7.09782712893383973096e+02) { for(i=n-1,di=(double)(i+i);i>0;i--){ temp = b; @@ -200,14 +200,14 @@ __ieee754_jn(int n, double x) } } } - b = (t*__ieee754_j0(x)/b); + b = (t*j0(x)/b); } } if(sgn==1) return -b; else return b; } double -__ieee754_yn(int n, double x) +yn(int n, double x) { int32_t i,hx,ix,lx; int32_t sign; @@ -224,8 +224,8 @@ __ieee754_yn(int n, double x) n = -n; sign = 1 - ((n&1)<<1); } - if(n==0) return(__ieee754_y0(x)); - if(n==1) return(sign*__ieee754_y1(x)); + if(n==0) return(y0(x)); + if(n==1) return(sign*y1(x)); if(ix==0x7ff00000) return zero; if(ix>=0x52D00000) { /* x > 2**302 */ /* (x >> n**2) @@ -250,8 +250,8 @@ __ieee754_yn(int n, double x) b = invsqrtpi*temp/sqrt(x); } else { u_int32_t high; - a = __ieee754_y0(x); - b = __ieee754_y1(x); + a = y0(x); + b = y1(x); /* quit if b is -inf */ GET_HIGH_WORD(high,b); for(i=1;i<n&&high!=0xfff00000;i++){ diff --git a/lib/libm/src/e_jnf.c b/lib/libm/src/e_jnf.c index 3512c9f51a2..c96d9670e27 100644 --- a/lib/libm/src/e_jnf.c +++ b/lib/libm/src/e_jnf.c @@ -27,7 +27,7 @@ one = 1.0000000000e+00; /* 0x3F800000 */ static const float zero = 0.0000000000e+00; float -__ieee754_jnf(int n, float x) +jnf(int n, float x) { int32_t i,hx,ix, sgn; float a, b, temp, di; @@ -45,16 +45,16 @@ __ieee754_jnf(int n, float x) x = -x; hx ^= 0x80000000; } - if(n==0) return(__ieee754_j0f(x)); - if(n==1) return(__ieee754_j1f(x)); + if(n==0) return(j0f(x)); + if(n==1) return(j1f(x)); sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ x = fabsf(x); if(ix==0||ix>=0x7f800000) /* if x is 0 or inf */ b = zero; else if((float)n<=x) { /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ - a = __ieee754_j0f(x); - b = __ieee754_j1f(x); + a = j0f(x); + b = j1f(x); for(i=1;i<n;i++){ temp = b; b = b*((float)(i+i)/x) - a; /* avoid underflow */ @@ -129,7 +129,7 @@ __ieee754_jnf(int n, float x) */ tmp = n; v = two/x; - tmp = tmp*__ieee754_logf(fabsf(v*tmp)); + tmp = tmp*logf(fabsf(v*tmp)); if(tmp<(float)8.8721679688e+01) { for(i=n-1,di=(float)(i+i);i>0;i--){ temp = b; @@ -153,14 +153,14 @@ __ieee754_jnf(int n, float x) } } } - b = (t*__ieee754_j0f(x)/b); + b = (t*j0f(x)/b); } } if(sgn==1) return -b; else return b; } float -__ieee754_ynf(int n, float x) +ynf(int n, float x) { int32_t i,hx,ix,ib; int32_t sign; @@ -177,12 +177,12 @@ __ieee754_ynf(int n, float x) n = -n; sign = 1 - ((n&1)<<1); } - if(n==0) return(__ieee754_y0f(x)); - if(n==1) return(sign*__ieee754_y1f(x)); + if(n==0) return(y0f(x)); + if(n==1) return(sign*y1f(x)); if(ix==0x7f800000) return zero; - a = __ieee754_y0f(x); - b = __ieee754_y1f(x); + a = y0f(x); + b = y1f(x); /* quit if b is -inf */ GET_FLOAT_WORD(ib,b); for(i=1;i<n&&ib!=0xff800000;i++){ diff --git a/lib/libm/src/e_lgamma_r.c b/lib/libm/src/e_lgamma_r.c index 1da673bc0c4..dbca95d5ea0 100644 --- a/lib/libm/src/e_lgamma_r.c +++ b/lib/libm/src/e_lgamma_r.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_lgamma_r.c,v 1.7 1995/05/10 20:45:42 jtc Exp $"; #endif -/* __ieee754_lgamma_r(x, signgamp) +/* lgamma_r(x, signgamp) * Reentrant version of the logarithm of the Gamma function * with user provide pointer for the sign of Gamma(x). * @@ -201,7 +201,7 @@ sin_pi(double x) double -__ieee754_lgamma_r(double x, int *signgamp) +lgamma_r(double x, int *signgamp) { double t,y,z,nadj,p,p1,p2,p3,q,r,w; int i,hx,lx,ix; @@ -216,15 +216,15 @@ __ieee754_lgamma_r(double x, int *signgamp) if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ if(hx<0) { *signgamp = -1; - return -__ieee754_log(-x); - } else return -__ieee754_log(x); + return - log(-x); + } else return - log(x); } if(hx<0) { if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ return one/zero; t = sin_pi(x); if(t==zero) return one/zero; /* -integer */ - nadj = __ieee754_log(pi/fabs(t*x)); + nadj = log(pi/fabs(t*x)); if(t<zero) *signgamp = -1; x = -x; } @@ -234,7 +234,7 @@ __ieee754_lgamma_r(double x, int *signgamp) /* for x < 2.0 */ else if(ix<0x40000000) { if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ - r = -__ieee754_log(x); + r = - log(x); if(ix>=0x3FE76944) {y = one-x; i= 0;} else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} else {y = x; i=2;} @@ -279,18 +279,18 @@ __ieee754_lgamma_r(double x, int *signgamp) case 5: z *= (y+4.0); /* FALLTHRU */ case 4: z *= (y+3.0); /* FALLTHRU */ case 3: z *= (y+2.0); /* FALLTHRU */ - r += __ieee754_log(z); break; + r += log(z); break; } /* 8.0 <= x < 2**58 */ } else if (ix < 0x43900000) { - t = __ieee754_log(x); + t = log(x); z = one/x; y = z*z; w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); r = (x-half)*(t-one)+w; } else /* 2**58 <= x <= inf */ - r = x*(__ieee754_log(x)-one); + r = x*(log(x)-one); if(hx<0) r = nadj - r; return r; } diff --git a/lib/libm/src/e_lgammaf_r.c b/lib/libm/src/e_lgammaf_r.c index 4f67523ecf9..1dfef89f9f9 100644 --- a/lib/libm/src/e_lgammaf_r.c +++ b/lib/libm/src/e_lgammaf_r.c @@ -137,7 +137,7 @@ sin_pif(float x) float -__ieee754_lgammaf_r(float x, int *signgamp) +lgammaf_r(float x, int *signgamp) { float t,y,z,nadj,p,p1,p2,p3,q,r,w; int i,hx,ix; @@ -152,15 +152,15 @@ __ieee754_lgammaf_r(float x, int *signgamp) if(ix<0x1c800000) { /* |x|<2**-70, return -log(|x|) */ if(hx<0) { *signgamp = -1; - return -__ieee754_logf(-x); - } else return -__ieee754_logf(x); + return - logf(-x); + } else return - logf(x); } if(hx<0) { if(ix>=0x4b000000) /* |x|>=2**23, must be -integer */ return one/zero; t = sin_pif(x); if(t==zero) return one/zero; /* -integer */ - nadj = __ieee754_logf(pi/fabsf(t*x)); + nadj = logf(pi/fabsf(t*x)); if(t<zero) *signgamp = -1; x = -x; } @@ -170,7 +170,7 @@ __ieee754_lgammaf_r(float x, int *signgamp) /* for x < 2.0 */ else if(ix<0x40000000) { if(ix<=0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */ - r = -__ieee754_logf(x); + r = - logf(x); if(ix>=0x3f3b4a20) {y = one-x; i= 0;} else if(ix>=0x3e6d3308) {y= x-(tc-one); i=1;} else {y = x; i=2;} @@ -215,18 +215,18 @@ __ieee754_lgammaf_r(float x, int *signgamp) case 5: z *= (y+(float)4.0); /* FALLTHRU */ case 4: z *= (y+(float)3.0); /* FALLTHRU */ case 3: z *= (y+(float)2.0); /* FALLTHRU */ - r += __ieee754_logf(z); break; + r += logf(z); break; } /* 8.0 <= x < 2**58 */ } else if (ix < 0x5c800000) { - t = __ieee754_logf(x); + t = logf(x); z = one/x; y = z*z; w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); r = (x-half)*(t-one)+w; } else /* 2**58 <= x <= inf */ - r = x*(__ieee754_logf(x)-one); + r = x*(logf(x)-one); if(hx<0) r = nadj - r; return r; } diff --git a/lib/libm/src/e_log.c b/lib/libm/src/e_log.c index 968faea8ce5..052deba253c 100644 --- a/lib/libm/src/e_log.c +++ b/lib/libm/src/e_log.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_log.c,v 1.8 1995/05/10 20:45:49 jtc Exp $"; #endif -/* __ieee754_log(x) +/* log(x) * Return the logrithm of x * * Method : @@ -83,7 +83,7 @@ Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ static const double zero = 0.0; double -__ieee754_log(double x) +log(double x) { double hfsq,f,s,z,R,w,t1,t2,dk; int32_t k,hx,i,j; diff --git a/lib/libm/src/e_log10.c b/lib/libm/src/e_log10.c index 7b2e09969da..ac8b87cfa03 100644 --- a/lib/libm/src/e_log10.c +++ b/lib/libm/src/e_log10.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_log10.c,v 1.9 1995/05/10 20:45:51 jtc Exp $"; #endif -/* __ieee754_log10(x) +/* log10(x) * Return the base 10 logarithm of x * * Method : @@ -59,7 +59,7 @@ log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ static const double zero = 0.0; double -__ieee754_log10(double x) +log10(double x) { double y,z; int32_t i,k,hx; @@ -81,6 +81,6 @@ __ieee754_log10(double x) hx = (hx&0x000fffff)|((0x3ff-i)<<20); y = (double)(k+i); SET_HIGH_WORD(x,hx); - z = y*log10_2lo + ivln10*__ieee754_log(x); + z = y*log10_2lo + ivln10*log(x); return z+y*log10_2hi; } diff --git a/lib/libm/src/e_log10f.c b/lib/libm/src/e_log10f.c index b491f166e38..d4777bf8409 100644 --- a/lib/libm/src/e_log10f.c +++ b/lib/libm/src/e_log10f.c @@ -29,7 +29,7 @@ log10_2lo = 7.9034151668e-07; /* 0x355427db */ static const float zero = 0.0; float -__ieee754_log10f(float x) +log10f(float x) { float y,z; int32_t i,k,hx; @@ -50,6 +50,6 @@ __ieee754_log10f(float x) hx = (hx&0x007fffff)|((0x7f-i)<<23); y = (float)(k+i); SET_FLOAT_WORD(x,hx); - z = y*log10_2lo + ivln10*__ieee754_logf(x); + z = y*log10_2lo + ivln10*logf(x); return z+y*log10_2hi; } diff --git a/lib/libm/src/e_log2.c b/lib/libm/src/e_log2.c new file mode 100644 index 00000000000..aed716670dc --- /dev/null +++ b/lib/libm/src/e_log2.c @@ -0,0 +1,74 @@ +/* @(#)e_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "math.h" +#include "math_private.h" + +static const double +ln2 = 0.6931471805599452862268, +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static const double zero = 0.0; + +double +log2(double x) +{ + double hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,hx,i,j; + u_int32_t lx; + + EXTRACT_WORDS(hx,lx,x); + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + GET_HIGH_WORD(hx,x); + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */ + k += (i>>20); + f = x-1.0; + dk = (double)k; + if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ + if (f==zero) + return (dk); + R = f*f*(0.5-0.33333333333333333*f); + return (dk-(R-f)/ln2); + } + s = f/(2.0+f); + z = s*s; + i = hx-0x6147a; + w = z*z; + j = 0x6b851-hx; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=0.5*f*f; + return (dk-(hfsq-s*(hfsq+R)-f)/ln2); + } else + return (dk-((s*(f-R))-f)/ln2); +} diff --git a/lib/libm/src/e_log2f.c b/lib/libm/src/e_log2f.c new file mode 100644 index 00000000000..c454775feff --- /dev/null +++ b/lib/libm/src/e_log2f.c @@ -0,0 +1,76 @@ +/* e_logf.c -- float version of e_log.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "math.h" +#include "math_private.h" + +static const float +ln2 = 0.6931471805599452862268, +two25 = 3.355443200e+07, /* 0x4c000000 */ +Lg1 = 6.6666668653e-01, /* 3F2AAAAB */ +Lg2 = 4.0000000596e-01, /* 3ECCCCCD */ +Lg3 = 2.8571429849e-01, /* 3E924925 */ +Lg4 = 2.2222198546e-01, /* 3E638E29 */ +Lg5 = 1.8183572590e-01, /* 3E3A3325 */ +Lg6 = 1.5313838422e-01, /* 3E1CD04F */ +Lg7 = 1.4798198640e-01; /* 3E178897 */ + +static const float zero = 0.0; + +float +log2f(float x) +{ + float hfsq,f,s,z,R,w,t1,t2,dk; + int32_t k,ix,i,j; + + GET_FLOAT_WORD(ix,x); + + k=0; + if (ix < 0x00800000) { /* x < 2**-126 */ + if ((ix&0x7fffffff)==0) + return -two25/zero; /* log(+-0)=-inf */ + if (ix<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 25; x *= two25; /* subnormal number, scale up x */ + GET_FLOAT_WORD(ix,x); + } + if (ix >= 0x7f800000) return x+x; + k += (ix>>23)-127; + ix &= 0x007fffff; + i = (ix+(0x95f64<<3))&0x800000; + SET_FLOAT_WORD(x,ix|(i^0x3f800000)); /* normalize x or x/2 */ + k += (i>>23); + dk = (float)k; + f = x-(float)1.0; + if((0x007fffff&(15+ix))<16) { /* |f| < 2**-20 */ + if (f==zero) + return (dk); + R = f*f*((float)0.5-(float)0.33333333333333333*f); + return (dk-(R-f)/ln2); + } + s = f/((float)2.0+f); + z = s*s; + i = ix-(0x6147a<<3); + w = z*z; + j = (0x6b851<<3)-ix; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=(float)0.5*f*f; + return (dk-(hfsq-s*(hfsq+R)-f)/ln2); + } else + return (dk-((s*(f-R))-f)/ln2); +} diff --git a/lib/libm/src/e_logf.c b/lib/libm/src/e_logf.c index 60d327a089f..9491341e6b2 100644 --- a/lib/libm/src/e_logf.c +++ b/lib/libm/src/e_logf.c @@ -35,7 +35,7 @@ Lg7 = 1.4798198640e-01; /* 3E178897 */ static const float zero = 0.0; float -__ieee754_logf(float x) +logf(float x) { float hfsq,f,s,z,R,w,t1,t2,dk; int32_t k,ix,i,j; diff --git a/lib/libm/src/e_pow.c b/lib/libm/src/e_pow.c index 4c4ad3bd112..2aa035eee83 100644 --- a/lib/libm/src/e_pow.c +++ b/lib/libm/src/e_pow.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_pow.c,v 1.9 1995/05/12 04:57:32 jtc Exp $"; #endif -/* __ieee754_pow(x,y) return x**y +/* pow(x,y) return x**y * * n * Method: Let x = 2 * (1+f) @@ -96,7 +96,7 @@ ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ double -__ieee754_pow(double x, double y) +pow(double x, double y) { double z,ax,z_h,z_l,p_h,p_l; double yy1,t1,t2,r,s,t,u,v,w; @@ -152,7 +152,7 @@ __ieee754_pow(double x, double y) if(hy==0x40000000) return x*x; /* y is 2 */ if(hy==0x3fe00000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ - return __ieee754_sqrt(x); + return sqrt(x); } } diff --git a/lib/libm/src/e_powf.c b/lib/libm/src/e_powf.c index ec93660cc3f..9e520f486b9 100644 --- a/lib/libm/src/e_powf.c +++ b/lib/libm/src/e_powf.c @@ -54,7 +54,7 @@ ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/ ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/ float -__ieee754_powf(float x, float y) +powf(float x, float y) { float z,ax,z_h,z_l,p_h,p_l; float yy1,t1,t2,r,s,t,u,v,w; @@ -103,7 +103,7 @@ __ieee754_powf(float x, float y) if(hy==0x40000000) return x*x; /* y is 2 */ if(hy==0x3f000000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ - return __ieee754_sqrtf(x); + return sqrtf(x); } ax = fabsf(x); diff --git a/lib/libm/src/e_remainder.c b/lib/libm/src/e_remainder.c index cd67c4410ff..623a13b141e 100644 --- a/lib/libm/src/e_remainder.c +++ b/lib/libm/src/e_remainder.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_remainder.c,v 1.8 1995/05/10 20:46:05 jtc Exp $"; #endif -/* __ieee754_remainder(x,p) +/* remainder(x,p) * Return : * returns x REM p = x - [x/p]*p as if in infinite * precise arithmetic, where [x/p] is the (infinite bit) @@ -30,7 +30,7 @@ static const double zero = 0.0; double -__ieee754_remainder(double x, double p) +remainder(double x, double p) { int32_t hx,hp; u_int32_t sx,lx,lp; @@ -50,7 +50,7 @@ __ieee754_remainder(double x, double p) return (x*p)/(x*p); - if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ + if (hp<=0x7fdfffff) x = fmod(x,p+p); /* now x < 2p */ if (((hx-hp)|(lx-lp))==0) return zero*x; x = fabs(x); p = fabs(p); diff --git a/lib/libm/src/e_remainderf.c b/lib/libm/src/e_remainderf.c index 36ec236732e..4405866914d 100644 --- a/lib/libm/src/e_remainderf.c +++ b/lib/libm/src/e_remainderf.c @@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_remainderf.c,v 1.4 1995/05/10 20:46:08 jtc Exp static const float zero = 0.0; float -__ieee754_remainderf(float x, float p) +remainderf(float x, float p) { int32_t hx,hp; u_int32_t sx; @@ -42,7 +42,7 @@ __ieee754_remainderf(float x, float p) return (x*p)/(x*p); - if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p); /* now x < 2p */ + if (hp<=0x7effffff) x = fmodf(x,p+p); /* now x < 2p */ if ((hx-hp)==0) return zero*x; x = fabsf(x); p = fabsf(p); diff --git a/lib/libm/src/e_scalb.c b/lib/libm/src/e_scalb.c index e51f5447d60..d07808896f1 100644 --- a/lib/libm/src/e_scalb.c +++ b/lib/libm/src/e_scalb.c @@ -15,7 +15,7 @@ static char rcsid[] = "$NetBSD: e_scalb.c,v 1.6 1995/05/10 20:46:09 jtc Exp $"; #endif /* - * __ieee754_scalb(x, fn) is provide for + * scalb(x, fn) is provide for * passing various standard test suite. One * should use scalbn() instead. */ @@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: e_scalb.c,v 1.6 1995/05/10 20:46:09 jtc Exp $"; #ifdef _SCALB_INT double -__ieee754_scalb(double x, int fn) +scalb(double x, int fn) { return scalbn(x, fn); } @@ -33,7 +33,7 @@ __ieee754_scalb(double x, int fn) #else double -__ieee754_scalb(double x, double fn) +scalb(double x, double fn) { if (isnan(x)||isnan(fn)) return x*fn; if (!finite(fn)) { diff --git a/lib/libm/src/e_scalbf.c b/lib/libm/src/e_scalbf.c index 58587f5d98c..e50179a1835 100644 --- a/lib/libm/src/e_scalbf.c +++ b/lib/libm/src/e_scalbf.c @@ -22,7 +22,7 @@ static char rcsid[] = "$NetBSD: e_scalbf.c,v 1.3 1995/05/10 20:46:12 jtc Exp $"; #ifdef _SCALB_INT float -__ieee754_scalbf(float x, int fn) +scalbf(float x, int fn) { return scalbnf(x,fn); } @@ -30,7 +30,7 @@ __ieee754_scalbf(float x, int fn) #else float -__ieee754_scalbf(float x, float fn) +scalbf(float x, float fn) { if (isnanf(x)||isnanf(fn)) return x*fn; if (!finitef(fn)) { diff --git a/lib/libm/src/e_sinh.c b/lib/libm/src/e_sinh.c index 03cb60b3ef3..68be7b5080f 100644 --- a/lib/libm/src/e_sinh.c +++ b/lib/libm/src/e_sinh.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $"; #endif -/* __ieee754_sinh(x) +/* sinh(x) * Method : * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 * 1. Replace x by |x| (sinh(-x) = -sinh(x)). @@ -38,7 +38,7 @@ static char rcsid[] = "$NetBSD: e_sinh.c,v 1.7 1995/05/10 20:46:13 jtc Exp $"; static const double one = 1.0, shuge = 1.0e307; double -__ieee754_sinh(double x) +sinh(double x) { double t,w,h; int32_t ix,jx; @@ -63,12 +63,12 @@ __ieee754_sinh(double x) } /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ - if (ix < 0x40862E42) return h*__ieee754_exp(fabs(x)); + if (ix < 0x40862E42) return h*exp(fabs(x)); /* |x| in [log(maxdouble), overflowthresold] */ GET_LOW_WORD(lx,x); if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(u_int32_t)0x8fb9f87d))) { - w = __ieee754_exp(0.5*fabs(x)); + w = exp(0.5*fabs(x)); t = h*w; return t*w; } diff --git a/lib/libm/src/e_sinhf.c b/lib/libm/src/e_sinhf.c index a4b27c77ff4..a593c488b95 100644 --- a/lib/libm/src/e_sinhf.c +++ b/lib/libm/src/e_sinhf.c @@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_sinhf.c,v 1.4 1995/05/10 20:46:15 jtc Exp $"; static const float one = 1.0, shuge = 1.0e37; float -__ieee754_sinhf(float x) +sinhf(float x) { float t,w,h; int32_t ix,jx; @@ -46,11 +46,11 @@ __ieee754_sinhf(float x) } /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ - if (ix < 0x42b17180) return h*__ieee754_expf(fabsf(x)); + if (ix < 0x42b17180) return h*expf(fabsf(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix<=0x42b2d4fc) { - w = __ieee754_expf((float)0.5*fabsf(x)); + w = expf((float)0.5*fabsf(x)); t = h*w; return t*w; } diff --git a/lib/libm/src/e_sqrt.c b/lib/libm/src/e_sqrt.c index 4cf344e064a..05355a33291 100644 --- a/lib/libm/src/e_sqrt.c +++ b/lib/libm/src/e_sqrt.c @@ -14,7 +14,7 @@ static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $"; #endif -/* __ieee754_sqrt(x) +/* sqrt(x) * Return correctly rounded sqrt. * ------------------------------------------ * | Use the hardware sqrt if you have one | @@ -90,7 +90,7 @@ static char rcsid[] = "$NetBSD: e_sqrt.c,v 1.8 1995/05/10 20:46:17 jtc Exp $"; static const double one = 1.0, tiny=1.0e-300; double -__ieee754_sqrt(double x) +sqrt(double x) { double z; int32_t sign = (int)0x80000000; diff --git a/lib/libm/src/e_sqrtf.c b/lib/libm/src/e_sqrtf.c index f886fecc583..2dee4848572 100644 --- a/lib/libm/src/e_sqrtf.c +++ b/lib/libm/src/e_sqrtf.c @@ -23,7 +23,7 @@ static char rcsid[] = "$NetBSD: e_sqrtf.c,v 1.4 1995/05/10 20:46:19 jtc Exp $"; static const float one = 1.0, tiny=1.0e-30; float -__ieee754_sqrtf(float x) +sqrtf(float x) { float z; int32_t sign = (int)0x80000000; diff --git a/lib/libm/src/k_standard.c b/lib/libm/src/k_standard.c deleted file mode 100644 index 2ed40b44b87..00000000000 --- a/lib/libm/src/k_standard.c +++ /dev/null @@ -1,773 +0,0 @@ -/* @(#)k_standard.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $"; -#endif - -#include "math.h" -#include "math_private.h" -#include <errno.h> -#include <stdio.h> /* fputs(), stderr */ - -#ifndef _USE_WRITE -#define WRITE2(u,v) fputs(u, stderr) -#else /* !defined(_USE_WRITE) */ -#include <unistd.h> /* write */ -#define WRITE2(u,v) write(2, u, v) -#endif /* !defined(_USE_WRITE) */ - -static const double zero = 0.0; /* used as const */ - -/* - * Standard conformance (non-IEEE) on exception cases. - * Mapping: - * 1 -- acos(|x|>1) - * 2 -- asin(|x|>1) - * 3 -- atan2(+-0,+-0) - * 4 -- hypot overflow - * 5 -- cosh overflow - * 6 -- exp overflow - * 7 -- exp underflow - * 8 -- y0(0) - * 9 -- y0(-ve) - * 10-- y1(0) - * 11-- y1(-ve) - * 12-- yn(0) - * 13-- yn(-ve) - * 14-- lgamma(finite) overflow - * 15-- lgamma(-integer) - * 16-- log(0) - * 17-- log(x<0) - * 18-- log10(0) - * 19-- log10(x<0) - * 20-- pow(0.0,0.0) - * 21-- pow(x,y) overflow - * 22-- pow(x,y) underflow - * 23-- pow(0,negative) - * 24-- pow(neg,non-integral) - * 25-- sinh(finite) overflow - * 26-- sqrt(negative) - * 27-- fmod(x,0) - * 28-- remainder(x,0) - * 29-- acosh(x<1) - * 30-- atanh(|x|>1) - * 31-- atanh(|x|=1) - * 32-- scalb overflow - * 33-- scalb underflow - * 34-- j0(|x|>X_TLOSS) - * 35-- y0(x>X_TLOSS) - * 36-- j1(|x|>X_TLOSS) - * 37-- y1(x>X_TLOSS) - * 38-- jn(|x|>X_TLOSS, n) - * 39-- yn(x>X_TLOSS, n) - * 40-- gamma(finite) overflow - * 41-- gamma(-integer) - * 42-- pow(NaN,0.0) - */ - - -double -__kernel_standard(double x, double y, int type) -{ - struct exception exc; -#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ -#define HUGE_VAL inf - double inf = 0.0; - - SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */ -#endif - -#ifdef _USE_WRITE - (void) fflush(stdout); -#endif - exc.arg1 = x; - exc.arg2 = y; - switch(type) { - case 1: - case 101: - /* acos(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "acos" : "acosf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if(_LIB_VERSION == _SVID_) { - (void) WRITE2("acos: DOMAIN error\n", 19); - } - errno = EDOM; - } - break; - case 2: - case 102: - /* asin(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "asin" : "asinf"; - exc.retval = zero; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if(_LIB_VERSION == _SVID_) { - (void) WRITE2("asin: DOMAIN error\n", 19); - } - errno = EDOM; - } - break; - case 3: - case 103: - /* atan2(+-0,+-0) */ - exc.arg1 = y; - exc.arg2 = x; - exc.type = DOMAIN; - exc.name = type < 100 ? "atan2" : "atan2f"; - exc.retval = zero; - if(_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if(_LIB_VERSION == _SVID_) { - (void) WRITE2("atan2: DOMAIN error\n", 20); - } - errno = EDOM; - } - break; - case 4: - case 104: - /* hypot(finite,finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "hypot" : "hypotf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 5: - case 105: - /* cosh(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "cosh" : "coshf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 6: - case 106: - /* exp(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "exp" : "expf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 7: - case 107: - /* exp(finite) underflow */ - exc.type = UNDERFLOW; - exc.name = type < 100 ? "exp" : "expf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 8: - case 108: - /* y0(0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "y0" : "y0f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y0: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 9: - case 109: - /* y0(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "y0" : "y0f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y0: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 10: - case 110: - /* y1(0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "y1" : "y1f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y1: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 11: - case 111: - /* y1(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "y1" : "y1f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("y1: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 12: - case 112: - /* yn(n,0) = -inf */ - exc.type = DOMAIN; /* should be SING for IEEE */ - exc.name = type < 100 ? "yn" : "ynf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("yn: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 13: - case 113: - /* yn(x<0) = NaN */ - exc.type = DOMAIN; - exc.name = type < 100 ? "yn" : "ynf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("yn: DOMAIN error\n", 17); - } - errno = EDOM; - } - break; - case 14: - case 114: - /* lgamma(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "lgamma" : "lgammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 15: - case 115: - /* lgamma(-integer) or lgamma(0) */ - exc.type = SING; - exc.name = type < 100 ? "lgamma" : "lgammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("lgamma: SING error\n", 19); - } - errno = EDOM; - } - break; - case 16: - case 116: - /* log(0) */ - exc.type = SING; - exc.name = type < 100 ? "log" : "logf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log: SING error\n", 16); - } - errno = EDOM; - } - break; - case 17: - case 117: - /* log(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "log" : "logf"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log: DOMAIN error\n", 18); - } - errno = EDOM; - } - break; - case 18: - case 118: - /* log10(0) */ - exc.type = SING; - exc.name = type < 100 ? "log10" : "log10f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log10: SING error\n", 18); - } - errno = EDOM; - } - break; - case 19: - case 119: - /* log10(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "log10" : "log10f"; - if (_LIB_VERSION == _SVID_) - exc.retval = -HUGE; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("log10: DOMAIN error\n", 20); - } - errno = EDOM; - } - break; - case 20: - case 120: - /* pow(0.0,0.0) */ - /* error only if _LIB_VERSION == _SVID_ */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - exc.retval = zero; - if (_LIB_VERSION != _SVID_) exc.retval = 1.0; - else if (!matherr(&exc)) { - (void) WRITE2("pow(0,0): DOMAIN error\n", 23); - errno = EDOM; - } - break; - case 21: - case 121: - /* pow(x,y) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "pow" : "powf"; - if (_LIB_VERSION == _SVID_) { - exc.retval = HUGE; - y *= 0.5; - if(x<zero&&rint(y)!=y) exc.retval = -HUGE; - } else { - exc.retval = HUGE_VAL; - y *= 0.5; - if(x<zero&&rint(y)!=y) exc.retval = -HUGE_VAL; - } - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 22: - case 122: - /* pow(x,y) underflow */ - exc.type = UNDERFLOW; - exc.name = type < 100 ? "pow" : "powf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 23: - case 123: - /* 0**neg */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - if (_LIB_VERSION == _SVID_) - exc.retval = zero; - else - exc.retval = -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("pow(0,neg): DOMAIN error\n", 25); - } - errno = EDOM; - } - break; - case 24: - case 124: - /* neg**non-integral */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - if (_LIB_VERSION == _SVID_) - exc.retval = zero; - else - exc.retval = zero/zero; /* X/Open allow NaN */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("neg**non-integral: DOMAIN error\n", 32); - } - errno = EDOM; - } - break; - case 25: - case 125: - /* sinh(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "sinh" : "sinhf"; - if (_LIB_VERSION == _SVID_) - exc.retval = ( (x>zero) ? HUGE : -HUGE); - else - exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 26: - case 126: - /* sqrt(x<0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "sqrt" : "sqrtf"; - if (_LIB_VERSION == _SVID_) - exc.retval = zero; - else - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("sqrt: DOMAIN error\n", 19); - } - errno = EDOM; - } - break; - case 27: - case 127: - /* fmod(x,0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "fmod" : "fmodf"; - if (_LIB_VERSION == _SVID_) - exc.retval = x; - else - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("fmod: DOMAIN error\n", 20); - } - errno = EDOM; - } - break; - case 28: - case 128: - /* remainder(x,0) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "remainder" : "remainderf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("remainder: DOMAIN error\n", 24); - } - errno = EDOM; - } - break; - case 29: - case 129: - /* acosh(x<1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "acosh" : "acoshf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("acosh: DOMAIN error\n", 20); - } - errno = EDOM; - } - break; - case 30: - case 130: - /* atanh(|x|>1) */ - exc.type = DOMAIN; - exc.name = type < 100 ? "atanh" : "atanhf"; - exc.retval = zero/zero; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("atanh: DOMAIN error\n", 20); - } - errno = EDOM; - } - break; - case 31: - case 131: - /* atanh(|x|=1) */ - exc.type = SING; - exc.name = type < 100 ? "atanh" : "atanhf"; - exc.retval = x/zero; /* sign(x)*inf */ - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("atanh: SING error\n", 18); - } - errno = EDOM; - } - break; - case 32: - case 132: - /* scalb overflow; SVID also returns +-HUGE_VAL */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "scalb" : "scalbf"; - exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 33: - case 133: - /* scalb underflow */ - exc.type = UNDERFLOW; - exc.name = type < 100 ? "scalb" : "scalbf"; - exc.retval = copysign(zero,x); - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 34: - case 134: - /* j0(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "j0" : "j0f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 35: - case 135: - /* y0(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "y0" : "y0f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 36: - case 136: - /* j1(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "j1" : "j1f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 37: - case 137: - /* y1(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "y1" : "y1f"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 38: - case 138: - /* jn(|x|>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "jn" : "jnf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 39: - case 139: - /* yn(x>X_TLOSS) */ - exc.type = TLOSS; - exc.name = type < 100 ? "yn" : "ynf"; - exc.retval = zero; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2(exc.name, 2); - (void) WRITE2(": TLOSS error\n", 14); - } - errno = ERANGE; - } - break; - case 40: - case 140: - /* gamma(finite) overflow */ - exc.type = OVERFLOW; - exc.name = type < 100 ? "gamma" : "gammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = ERANGE; - else if (!matherr(&exc)) { - errno = ERANGE; - } - break; - case 41: - case 141: - /* gamma(-integer) or gamma(0) */ - exc.type = SING; - exc.name = type < 100 ? "gamma" : "gammaf"; - if (_LIB_VERSION == _SVID_) - exc.retval = HUGE; - else - exc.retval = HUGE_VAL; - if (_LIB_VERSION == _POSIX_) - errno = EDOM; - else if (!matherr(&exc)) { - if (_LIB_VERSION == _SVID_) { - (void) WRITE2("gamma: SING error\n", 18); - } - errno = EDOM; - } - break; - case 42: - case 142: - /* pow(NaN,0.0) */ - /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ - exc.type = DOMAIN; - exc.name = type < 100 ? "pow" : "powf"; - exc.retval = x; - if (_LIB_VERSION == _IEEE_ || - _LIB_VERSION == _POSIX_) exc.retval = 1.0; - else if (!matherr(&exc)) { - errno = EDOM; - } - break; - } - return exc.retval; -} diff --git a/lib/libm/src/math_private.h b/lib/libm/src/math_private.h index cdfd07affe1..0fc4f6a78d3 100644 --- a/lib/libm/src/math_private.h +++ b/lib/libm/src/math_private.h @@ -1,4 +1,4 @@ -/* $OpenBSD: math_private.h,v 1.9 2008/07/24 09:40:16 martynas Exp $ */ +/* $OpenBSD: math_private.h,v 1.10 2008/09/07 20:36:09 martynas Exp $ */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. @@ -213,73 +213,15 @@ do { \ #endif #endif -/* ieee style elementary functions */ -extern double __ieee754_sqrt(double); -extern double __ieee754_acos(double); -extern double __ieee754_acosh(double); -extern double __ieee754_log(double); -extern double __ieee754_atanh(double); -extern double __ieee754_asin(double); -extern double __ieee754_atan2(double,double); -extern double __ieee754_exp(double); -extern double __ieee754_cosh(double); -extern double __ieee754_fmod(double,double); -extern double __ieee754_pow(double,double); -extern double __ieee754_lgamma_r(double,int *); -extern double __ieee754_gamma_r(double,int *); -extern double __ieee754_lgamma(double); -extern double __ieee754_gamma(double); -extern double __ieee754_log10(double); -extern double __ieee754_sinh(double); -extern double __ieee754_hypot(double,double); -extern double __ieee754_j0(double); -extern double __ieee754_j1(double); -extern double __ieee754_y0(double); -extern double __ieee754_y1(double); -extern double __ieee754_jn(int,double); -extern double __ieee754_yn(int,double); -extern double __ieee754_remainder(double,double); -extern int __ieee754_rem_pio2(double,double*); -extern double __ieee754_scalb(double,double); - /* fdlibm kernel function */ -extern double __kernel_standard(double,double,int); +extern int __ieee754_rem_pio2(double,double*); extern double __kernel_sin(double,double,int); extern double __kernel_cos(double,double); extern double __kernel_tan(double,double,int); extern int __kernel_rem_pio2(double*,double*,int,int,int,const int*); - -/* ieee style elementary float functions */ -extern float __ieee754_sqrtf(float); -extern float __ieee754_acosf(float); -extern float __ieee754_acoshf(float); -extern float __ieee754_logf(float); -extern float __ieee754_atanhf(float); -extern float __ieee754_asinf(float); -extern float __ieee754_atan2f(float,float); -extern float __ieee754_expf(float); -extern float __ieee754_coshf(float); -extern float __ieee754_fmodf(float,float); -extern float __ieee754_powf(float,float); -extern float __ieee754_lgammaf_r(float,int *); -extern float __ieee754_gammaf_r(float,int *); -extern float __ieee754_lgammaf(float); -extern float __ieee754_gammaf(float); -extern float __ieee754_log10f(float); -extern float __ieee754_sinhf(float); -extern float __ieee754_hypotf(float,float); -extern float __ieee754_j0f(float); -extern float __ieee754_j1f(float); -extern float __ieee754_y0f(float); -extern float __ieee754_y1f(float); -extern float __ieee754_jnf(int,float); -extern float __ieee754_ynf(int,float); -extern float __ieee754_remainderf(float,float); -extern int __ieee754_rem_pio2f(float,float*); -extern float __ieee754_scalbf(float,float); - /* float versions of fdlibm kernel functions */ +extern int __ieee754_rem_pio2f(float,float*); extern float __kernel_sinf(float,float,int); extern float __kernel_cosf(float,float); extern float __kernel_tanf(float,float,int); diff --git a/lib/libm/src/s_asinh.c b/lib/libm/src/s_asinh.c index da49239a015..7398aa9d057 100644 --- a/lib/libm/src/s_asinh.c +++ b/lib/libm/src/s_asinh.c @@ -45,13 +45,13 @@ asinh(double x) if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x41b00000) { /* |x| > 2**28 */ - w = __ieee754_log(fabs(x))+ln2; + w = log(fabs(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabs(x); - w = __ieee754_log(2.0*t+one/(__ieee754_sqrt(x*x+one)+t)); + w = log(2.0*t+one/(sqrt(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; - w =log1p(fabs(x)+t/(one+__ieee754_sqrt(one+t))); + w =log1p(fabs(x)+t/(one+sqrt(one+t))); } if(hx>0) return w; else return -w; } diff --git a/lib/libm/src/s_asinhf.c b/lib/libm/src/s_asinhf.c index 50e60b4d29e..e6426142985 100644 --- a/lib/libm/src/s_asinhf.c +++ b/lib/libm/src/s_asinhf.c @@ -37,13 +37,13 @@ asinhf(float x) if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4d800000) { /* |x| > 2**28 */ - w = __ieee754_logf(fabsf(x))+ln2; + w = logf(fabsf(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabsf(x); - w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t)); + w = logf((float)2.0*t+one/(sqrtf(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; - w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); + w =log1pf(fabsf(x)+t/(one+sqrtf(one+t))); } if(hx>0) return w; else return -w; } diff --git a/lib/libm/src/s_cabs.c b/lib/libm/src/s_cabs.c new file mode 100644 index 00000000000..d2f3f942c3f --- /dev/null +++ b/lib/libm/src/s_cabs.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_cabs.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double +cabs(double complex z) +{ + return hypot(__real__ z, __imag__ z); +} diff --git a/lib/libc/stdlib/strtof.c b/lib/libm/src/s_cabsf.c index 8c8db47ad82..d4d22f2dbb5 100644 --- a/lib/libc/stdlib/strtof.c +++ b/lib/libm/src/s_cabsf.c @@ -1,8 +1,6 @@ -/* $OpenBSD: strtof.c,v 1.1 2008/06/13 21:04:24 landry Exp $ */ - +/* $OpenBSD: s_cabsf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ /* - * Copyright (c) 2008 Landry Breuil - * All rights reserved. + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,23 +15,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <errno.h> -#include <limits.h> -#include <stdlib.h> +#include <complex.h> #include <math.h> float -strtof(const char *s00, char **se) +cabsf(float complex z) { - double d; - - d = strtod(s00, se); - if (d > FLT_MAX) { - errno = ERANGE; - return (FLT_MAX); - } else if (d < -FLT_MAX) { - errno = ERANGE; - return (-FLT_MAX); - } - return ((float) d); + return hypotf(__real__ z, __imag__ z); } diff --git a/lib/libm/src/s_cacos.c b/lib/libm/src/s_cacos.c new file mode 100644 index 00000000000..96d26626b98 --- /dev/null +++ b/lib/libm/src/s_cacos.c @@ -0,0 +1,60 @@ +/* $OpenBSD: s_cacos.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cacos() + * + * Complex circular arc cosine + * + * + * + * SYNOPSIS: + * + * double complex cacos(); + * double complex z, w; + * + * w = cacos (z); + * + * + * + * DESCRIPTION: + * + * + * w = arccos z = PI/2 - arcsin z. + * + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 1.6e-15 2.8e-16 + * IEEE -10,+10 30000 1.8e-14 2.2e-15 + */ + +#include <complex.h> +#include <math.h> + +double complex +cacos(double complex z) +{ + double complex w; + + w = casin (z); + w = (M_PI_2 - creal (w)) - cimag (w) * I; + return (w); +} diff --git a/lib/libm/src/s_cacosf.c b/lib/libm/src/s_cacosf.c new file mode 100644 index 00000000000..5a644c15bd1 --- /dev/null +++ b/lib/libm/src/s_cacosf.c @@ -0,0 +1,60 @@ +/* $OpenBSD: s_cacosf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cacosf() + * + * Complex circular arc cosine + * + * + * + * SYNOPSIS: + * + * void cacosf(); + * cmplxf z, w; + * + * cacosf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * + * w = arccos z = PI/2 - arcsin z. + * + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.2e-6 1.2e-6 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +cacosf(float complex z) +{ + float complex w; + + w = casinf( z ); + w = (M_PI_2 - creal (w)) - cimag (w) * I; + return (w); +} diff --git a/lib/libm/src/s_cacosh.c b/lib/libm/src/s_cacosh.c new file mode 100644 index 00000000000..43ba99ad6f9 --- /dev/null +++ b/lib/libm/src/s_cacosh.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_cacosh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cacosh + * + * Complex inverse hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * double complex cacosh(); + * double complex z, w; + * + * w = cacosh (z); + * + * + * + * DESCRIPTION: + * + * acosh z = i acos z . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.6e-14 2.1e-15 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +cacosh(double complex z) +{ + double complex w; + + w = I * cacos (z); + return (w); +} diff --git a/lib/libm/src/s_cacoshf.c b/lib/libm/src/s_cacoshf.c new file mode 100644 index 00000000000..d81f7843c91 --- /dev/null +++ b/lib/libm/src/s_cacoshf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_cacoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cacoshf + * + * Complex inverse hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * float complex cacoshf(); + * float complex z, w; + * + * w = cacoshf (z); + * + * + * + * DESCRIPTION: + * + * acosh z = i acos z . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.6e-14 2.1e-15 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +cacoshf(float complex z) +{ + float complex w; + + w = I * cacosf (z); + return (w); +} diff --git a/lib/libm/src/s_carg.c b/lib/libm/src/s_carg.c new file mode 100644 index 00000000000..db51662a1d9 --- /dev/null +++ b/lib/libm/src/s_carg.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_carg.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double +carg(double complex z) +{ + return atan2 (__imag__ z, __real__ z); +} diff --git a/lib/libm/src/s_cargf.c b/lib/libm/src/s_cargf.c new file mode 100644 index 00000000000..12dbcde753d --- /dev/null +++ b/lib/libm/src/s_cargf.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_cargf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +float +cargf(float complex z) +{ + return atan2f (__imag__ z, __real__ z); +} diff --git a/lib/libm/src/s_casin.c b/lib/libm/src/s_casin.c new file mode 100644 index 00000000000..1c1b53541bb --- /dev/null +++ b/lib/libm/src/s_casin.c @@ -0,0 +1,129 @@ +/* $OpenBSD: s_casin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* casin() + * + * Complex circular arc sine + * + * + * + * SYNOPSIS: + * + * double complex casin(); + * double complex z, w; + * + * w = casin (z); + * + * + * + * DESCRIPTION: + * + * Inverse complex sine: + * + * 2 + * w = -i clog( iz + csqrt( 1 - z ) ). + * + * casin(z) = -i casinh(iz) + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 10100 2.1e-15 3.4e-16 + * IEEE -10,+10 30000 2.2e-14 2.7e-15 + * Larger relative error can be observed for z near zero. + * Also tested by csin(casin(z)) = z. + */ + +#include <complex.h> +#include <math.h> + +double complex +casin(double complex z) +{ + double complex w; + static double complex ca, ct, zz, z2; + double x, y; + + x = creal (z); + y = cimag (z); + + if (y == 0.0) { + if (fabs(x) > 1.0) { + w = M_PI_2 + 0.0 * I; + /*mtherr ("casin", DOMAIN);*/ + } + else { + w = asin (x) + 0.0 * I; + } + return (w); + } + + /* Power series expansion */ + /* + b = cabs(z); + if( b < 0.125 ) { + z2.r = (x - y) * (x + y); + z2.i = 2.0 * x * y; + + cn = 1.0; + n = 1.0; + ca.r = x; + ca.i = y; + sum.r = x; + sum.i = y; + do { + ct.r = z2.r * ca.r - z2.i * ca.i; + ct.i = z2.r * ca.i + z2.i * ca.r; + ca.r = ct.r; + ca.i = ct.i; + + cn *= n; + n += 1.0; + cn /= n; + n += 1.0; + b = cn/n; + + ct.r *= b; + ct.i *= b; + sum.r += ct.r; + sum.i += ct.i; + b = fabs(ct.r) + fabs(ct.i); + } + while( b > MACHEP ); + w->r = sum.r; + w->i = sum.i; + return; + } + */ + + ca = x + y * I; + ct = ca * I; + /* sqrt( 1 - z*z) */ + /* cmul( &ca, &ca, &zz ) */ + /*x * x - y * y */ + zz = (x - y) * (x + y) + (2.0 * x * y) * I; + + zz = 1.0 - creal(zz) - cimag(zz) * I; + z2 = csqrt (zz); + + zz = ct + z2; + zz = clog (zz); + /* multiply by 1/i = -i */ + w = zz * (-1.0 * I); + return (w); +} diff --git a/lib/libm/src/s_casinf.c b/lib/libm/src/s_casinf.c new file mode 100644 index 00000000000..84b2096a4fc --- /dev/null +++ b/lib/libm/src/s_casinf.c @@ -0,0 +1,132 @@ +/* $OpenBSD: s_casinf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* casinf() + * + * Complex circular arc sine + * + * + * + * SYNOPSIS: + * + * void casinf(); + * cmplxf z, w; + * + * casinf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * Inverse complex sine: + * + * 2 + * w = -i clog( iz + csqrt( 1 - z ) ). + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.1e-5 1.5e-6 + * Larger relative error can be observed for z near zero. + * + */ + +#include <complex.h> +#include <math.h> + +float complex +casinf(float complex z) +{ + float complex w; + float x, y; + static float complex ca, ct, zz, z2; + /* + float cn, n; + static float a, b, s, t, u, v, y2; + static cmplxf sum; + */ + + x = creal(z); + y = cimag(z); + + if(y == 0.0f) { + if(fabsf(x) > 1.0f) { + w = M_PI_2 + 0.0f * I; + /*mtherr( "casinf", DOMAIN );*/ + } + else { + w = asinf (x) + 0.0f * I; + } + return (w); + } + + /* Power series expansion */ + /* + b = cabsf(z); + if(b < 0.125) { + z2.r = (x - y) * (x + y); + z2.i = 2.0 * x * y; + + cn = 1.0; + n = 1.0; + ca.r = x; + ca.i = y; + sum.r = x; + sum.i = y; + do { + ct.r = z2.r * ca.r - z2.i * ca.i; + ct.i = z2.r * ca.i + z2.i * ca.r; + ca.r = ct.r; + ca.i = ct.i; + + cn *= n; + n += 1.0; + cn /= n; + n += 1.0; + b = cn/n; + + ct.r *= b; + ct.i *= b; + sum.r += ct.r; + sum.i += ct.i; + b = fabsf(ct.r) + fabsf(ct.i); + } + while(b > MACHEPF); + w->r = sum.r; + w->i = sum.i; + return; + } + */ + + + ca = x + y * I; + ct = ca * I; /* iz */ + /* sqrt( 1 - z*z) */ + /* cmul( &ca, &ca, &zz ) */ + /*x * x - y * y */ + zz = (x - y) * (x + y) + (2.0f * x * y) * I; + zz = 1.0f - creal(zz) - cimag(zz) * I; + z2 = csqrtf (zz); + + zz = ct + z2; + zz = clogf (zz); + /* multiply by 1/i = -i */ + w = zz * (-1.0f * I); + return (w); +} diff --git a/lib/libm/src/s_casinh.c b/lib/libm/src/s_casinh.c new file mode 100644 index 00000000000..a249cf15ede --- /dev/null +++ b/lib/libm/src/s_casinh.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_casinh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* casinh + * + * Complex inverse hyperbolic sine + * + * + * + * SYNOPSIS: + * + * double complex casinh(); + * double complex z, w; + * + * w = casinh (z); + * + * + * + * DESCRIPTION: + * + * casinh z = -i casin iz . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-14 2.6e-15 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +casinh(double complex z) +{ + double complex w; + + w = -1.0 * I * casin (z * I); + return (w); +} diff --git a/lib/libm/src/s_casinhf.c b/lib/libm/src/s_casinhf.c new file mode 100644 index 00000000000..334c29bcab2 --- /dev/null +++ b/lib/libm/src/s_casinhf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_casinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* casinhf + * + * Complex inverse hyperbolic sine + * + * + * + * SYNOPSIS: + * + * float complex casinhf(); + * float complex z, w; + * + * w = casinhf (z); + * + * + * + * DESCRIPTION: + * + * casinh z = -i casin iz . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-14 2.6e-15 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +casinhf(float complex z) +{ + float complex w; + + w = -1.0f * I * casinf (z * I); + return (w); +} diff --git a/lib/libm/src/s_catan.c b/lib/libm/src/s_catan.c new file mode 100644 index 00000000000..ddd7940456e --- /dev/null +++ b/lib/libm/src/s_catan.c @@ -0,0 +1,126 @@ +/* $OpenBSD: s_catan.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* catan() + * + * Complex circular arc tangent + * + * + * + * SYNOPSIS: + * + * double complex catan(); + * double complex z, w; + * + * w = catan (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * 1 ( 2x ) + * Re w = - arctan(-----------) + k PI + * 2 ( 2 2) + * (1 - x - y ) + * + * ( 2 2) + * 1 (x + (y+1) ) + * Im w = - log(------------) + * 4 ( 2 2) + * (x + (y-1) ) + * + * Where k is an arbitrary integer. + * + * catan(z) = -i catanh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5900 1.3e-16 7.8e-18 + * IEEE -10,+10 30000 2.3e-15 8.5e-17 + * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2, + * had peak relative error 1.5e-16, rms relative error + * 2.9e-17. See also clog(). + */ + +#include <complex.h> +#include <math.h> + +#define MAXNUM 1.0e308 + +static const double DP1 = 3.14159265160560607910E0; +static const double DP2 = 1.98418714791870343106E-9; +static const double DP3 = 1.14423774522196636802E-17; + +static double +_redupi(double x) +{ + double t; + long i; + + t = x/M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +double complex +catan(double complex z) +{ + double complex w; + double a, t, x, x2, y; + + x = creal (z); + y = cimag (z); + + if ((x == 0.0) && (y > 1.0)) + goto ovrf; + + x2 = x * x; + a = 1.0 - x2 - (y * y); + if (a == 0.0) + goto ovrf; + + t = 0.5 * atan2 (2.0 * x, a); + w = _redupi (t); + + t = y - 1.0; + a = x2 + (t * t); + if (a == 0.0) + goto ovrf; + + t = y + 1.0; + a = (x2 + (t * t))/a; + w = w + (0.25 * log (a)) * I; + return (w); + +ovrf: + /*mtherr ("catan", OVERFLOW);*/ + w = MAXNUM + MAXNUM * I; + return (w); +} diff --git a/lib/libm/src/s_catanf.c b/lib/libm/src/s_catanf.c new file mode 100644 index 00000000000..e112e7f090a --- /dev/null +++ b/lib/libm/src/s_catanf.c @@ -0,0 +1,124 @@ +/* $OpenBSD: s_catanf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* catanf() + * + * Complex circular arc tangent + * + * + * + * SYNOPSIS: + * + * float complex catanf(); + * float complex z, w; + * + * w = catanf( z ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * 1 ( 2x ) + * Re w = - arctan(-----------) + k PI + * 2 ( 2 2) + * (1 - x - y ) + * + * ( 2 2) + * 1 (x + (y+1) ) + * Im w = - log(------------) + * 4 ( 2 2) + * (x + (y-1) ) + * + * Where k is an arbitrary integer. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-6 5.2e-8 + * + */ + +#include <complex.h> +#include <math.h> + +#define MAXNUMF 1.0e38F + +static const double DP1 = 3.140625; +static const double DP2 = 9.67502593994140625E-4; +static const double DP3 = 1.509957990978376432E-7; + +static float +_redupif(float xx) +{ + float x, t; + long i; + + x = xx; + t = x/(float)M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return(t); +} + +float complex +catanf(float complex z) +{ + float complex w; + float a, t, x, x2, y; + + x = creal (z); + y = cimag (z); + + if((x == 0.0f) && (y > 1.0f)) + goto ovrf; + + x2 = x * x; + a = 1.0f - x2 - (y * y); + if (a == 0.0f) + goto ovrf; + + t = 0.5f * atan2f(2.0f * x, a); + w = _redupif(t); + + t = y - 1.0f; + a = x2 + (t * t); + if(a == 0.0f) + goto ovrf; + + t = y + 1.0f; + a = (x2 + (t * t))/a; + w = w + (0.25f * logf (a)) * I; + return (w); + +ovrf: + /*mtherr( "catanf", OVERFLOW );*/ + w = MAXNUMF + MAXNUMF * I; + return (w); +} diff --git a/lib/libm/src/s_catanh.c b/lib/libm/src/s_catanh.c new file mode 100644 index 00000000000..7a6d6f99646 --- /dev/null +++ b/lib/libm/src/s_catanh.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_catanh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* catanh + * + * Complex inverse hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * double complex catanh(); + * double complex z, w; + * + * w = catanh (z); + * + * + * + * DESCRIPTION: + * + * Inverse tanh, equal to -i catan (iz); + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-16 6.2e-17 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +catanh(double complex z) +{ + double complex w; + + w = -1.0 * I * catan (z * I); + return (w); +} diff --git a/lib/libm/src/s_catanhf.c b/lib/libm/src/s_catanhf.c new file mode 100644 index 00000000000..35fc8f7541d --- /dev/null +++ b/lib/libm/src/s_catanhf.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_catanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* catanhf + * + * Complex inverse hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * float complex catanhf(); + * float complex z, w; + * + * w = catanhf (z); + * + * + * + * DESCRIPTION: + * + * Inverse tanh, equal to -i catan (iz); + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.3e-16 6.2e-17 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +catanhf(float complex z) +{ + float complex w; + + w = -1.0f * I * catanf (z * I); + return (w); +} diff --git a/lib/libm/src/s_ccos.c b/lib/libm/src/s_ccos.c new file mode 100644 index 00000000000..264143ab24c --- /dev/null +++ b/lib/libm/src/s_ccos.c @@ -0,0 +1,84 @@ +/* $OpenBSD: s_ccos.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ccos() + * + * Complex circular cosine + * + * + * + * SYNOPSIS: + * + * double complex ccos(); + * double complex z, w; + * + * w = ccos (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = cos x cosh y - i sin x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 4.5e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + */ + +#include <complex.h> +#include <math.h> + +/* calculate cosh and sinh */ + +static void +_cchsh(double x, double *c, double *s) +{ + double e, ei; + + if (fabs(x) <= 0.5) { + *c = cosh(x); + *s = sinh(x); + } + else { + e = exp(x); + ei = 0.5/e; + e = 0.5 * e; + *s = e - ei; + *c = e + ei; + } +} + +double complex +ccos(double complex z) +{ + double complex w; + double ch, sh; + + _cchsh( cimag(z), &ch, &sh ); + w = cos(creal (z)) * ch - (sin (creal (z)) * sh) * I; + return (w); +} diff --git a/lib/libm/src/s_ccosf.c b/lib/libm/src/s_ccosf.c new file mode 100644 index 00000000000..299e06b1276 --- /dev/null +++ b/lib/libm/src/s_ccosf.c @@ -0,0 +1,84 @@ +/* $OpenBSD: s_ccosf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ccosf() + * + * Complex circular cosine + * + * + * + * SYNOPSIS: + * + * void ccosf(); + * cmplxf z, w; + * + * ccosf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = cos x cosh y - i sin x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.8e-7 5.5e-8 + */ + +#include <complex.h> +#include <math.h> + +/* calculate cosh and sinh */ + +static void +_cchshf(float xx, float *c, float *s) +{ + float x, e, ei; + + x = xx; + if(fabsf(x) <= 0.5f) { + *c = coshf(x); + *s = sinhf(x); + } + else { + e = expf(x); + ei = 0.5f/e; + e = 0.5f * e; + *s = e - ei; + *c = e + ei; + } +} + +float complex +ccosf(float complex z) +{ + float complex w; + float ch, sh; + + _cchshf( cimag(z), &ch, &sh ); + w = cosf( creal(z) ) * ch + ( -sinf( creal(z) ) * sh) * I; + return (w); +} diff --git a/lib/libm/src/s_ccosh.c b/lib/libm/src/s_ccosh.c new file mode 100644 index 00000000000..0267b6f2a15 --- /dev/null +++ b/lib/libm/src/s_ccosh.c @@ -0,0 +1,58 @@ +/* $OpenBSD: s_ccosh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ccosh + * + * Complex hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * double complex ccosh(); + * double complex z, w; + * + * w = ccosh (z); + * + * + * + * DESCRIPTION: + * + * ccosh(z) = cosh x cos y + i sinh x sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.9e-16 8.1e-17 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +ccosh(double complex z) +{ + double complex w; + double x, y; + + x = creal(z); + y = cimag(z); + w = cosh (x) * cos (y) + (sinh (x) * sin (y)) * I; + return (w); +} diff --git a/lib/libm/src/s_ccoshf.c b/lib/libm/src/s_ccoshf.c new file mode 100644 index 00000000000..527a47afb98 --- /dev/null +++ b/lib/libm/src/s_ccoshf.c @@ -0,0 +1,58 @@ +/* $OpenBSD: s_ccoshf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ccoshf + * + * Complex hyperbolic cosine + * + * + * + * SYNOPSIS: + * + * float complex ccoshf(); + * float complex z, w; + * + * w = ccoshf (z); + * + * + * + * DESCRIPTION: + * + * ccosh(z) = cosh x cos y + i sinh x sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 2.9e-16 8.1e-17 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +ccoshf(float complex z) +{ + float complex w; + float x, y; + + x = creal(z); + y = cimag(z); + w = coshf (x) * cosf (y) + (sinhf (x) * sinf (y)) * I; + return (w); +} diff --git a/lib/libm/src/s_cexp.c b/lib/libm/src/s_cexp.c new file mode 100644 index 00000000000..52241a8eb5e --- /dev/null +++ b/lib/libm/src/s_cexp.c @@ -0,0 +1,70 @@ +/* $OpenBSD: s_cexp.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cexp() + * + * Complex exponential function + * + * + * + * SYNOPSIS: + * + * double complex cexp (); + * double complex z, w; + * + * w = cexp (z); + * + * + * + * DESCRIPTION: + * + * Returns the exponential of the complex argument z + * into the complex result w. + * + * If + * z = x + iy, + * r = exp(x), + * + * then + * + * w = r cos y + i r sin y. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8700 3.7e-17 1.1e-17 + * IEEE -10,+10 30000 3.0e-16 8.7e-17 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +cexp(double complex z) +{ + double complex w; + double r, x, y; + + x = creal (z); + y = cimag (z); + r = exp (x); + w = r * cos (y) + r * sin (y) * I; + return (w); +} diff --git a/lib/libm/src/s_cexpf.c b/lib/libm/src/s_cexpf.c new file mode 100644 index 00000000000..041bf84318d --- /dev/null +++ b/lib/libm/src/s_cexpf.c @@ -0,0 +1,67 @@ +/* $OpenBSD: s_cexpf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cexpf() + * + * Complex exponential function + * + * + * + * SYNOPSIS: + * + * void cexpf(); + * cmplxf z, w; + * + * cexpf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * Returns the exponential of the complex argument z + * into the complex result w. + * + * If + * z = x + iy, + * r = exp(x), + * + * then + * + * w = r cos y + i r sin y. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.4e-7 4.5e-8 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +cexpf(float complex z) +{ + float complex w; + float r; + + r = expf( creal(z) ); + w = r * cosf( cimag(z) ) + r * sinf( cimag(z) ) * I; + return (w); +} diff --git a/lib/libm/src/s_cimag.c b/lib/libm/src/s_cimag.c new file mode 100644 index 00000000000..85aaa2975d1 --- /dev/null +++ b/lib/libm/src/s_cimag.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_cimag.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double +cimag(double complex z) +{ + return __imag__ z; +} diff --git a/lib/libm/src/s_cimagf.c b/lib/libm/src/s_cimagf.c new file mode 100644 index 00000000000..609851fbbda --- /dev/null +++ b/lib/libm/src/s_cimagf.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_cimagf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +float +cimagf(float complex z) +{ + return __imag__ z; +} diff --git a/lib/libm/src/s_clog.c b/lib/libm/src/s_clog.c new file mode 100644 index 00000000000..31163700607 --- /dev/null +++ b/lib/libm/src/s_clog.c @@ -0,0 +1,72 @@ +/* $OpenBSD: s_clog.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* clog.c + * + * Complex natural logarithm + * + * + * + * SYNOPSIS: + * + * double complex clog(); + * double complex z, w; + * + * w = clog (z); + * + * + * + * DESCRIPTION: + * + * Returns complex logarithm to the base e (2.718...) of + * the complex argument x. + * + * If z = x + iy, r = sqrt( x**2 + y**2 ), + * then + * w = log(r) + i arctan(y/x). + * + * The arctangent ranges from -PI to +PI. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 7000 8.5e-17 1.9e-17 + * IEEE -10,+10 30000 5.0e-15 1.1e-16 + * + * Larger relative error can be observed for z near 1 +i0. + * In IEEE arithmetic the peak absolute error is 5.2e-16, rms + * absolute error 1.0e-16. + */ + +#include <complex.h> +#include <math.h> + +double complex +clog(double complex z) +{ + double complex w; + double p, rr; + + /*rr = sqrt( z->r * z->r + z->i * z->i );*/ + rr = cabs(z); + p = log(rr); + rr = atan2 (cimag (z), creal (z)); + w = p + rr * I; + return (w); +} diff --git a/lib/libm/src/s_clogf.c b/lib/libm/src/s_clogf.c new file mode 100644 index 00000000000..2cea0f218be --- /dev/null +++ b/lib/libm/src/s_clogf.c @@ -0,0 +1,72 @@ +/* $OpenBSD: s_clogf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* clogf.c + * + * Complex natural logarithm + * + * + * + * SYNOPSIS: + * + * void clogf(); + * cmplxf z, w; + * + * clogf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * Returns complex logarithm to the base e (2.718...) of + * the complex argument x. + * + * If z = x + iy, r = sqrt( x**2 + y**2 ), + * then + * w = log(r) + i arctan(y/x). + * + * The arctangent ranges from -PI to +PI. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.9e-6 6.2e-8 + * + * Larger relative error can be observed for z near 1 +i0. + * In IEEE arithmetic the peak absolute error is 3.1e-7. + * + */ + +#include <complex.h> +#include <math.h> + +float complex +clogf(float complex z) +{ + float complex w; + float p, rr, x, y; + + x = creal(z); + y = cimag(z); + rr = atan2f(y, x); + p = cabsf(z); + p = logf(p); + w = p + rr * I; + return (w); +} diff --git a/lib/libm/src/s_conj.c b/lib/libm/src/s_conj.c new file mode 100644 index 00000000000..fd38a9d034c --- /dev/null +++ b/lib/libm/src/s_conj.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_conj.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double complex +conj(double complex z) +{ + return ~z; +} diff --git a/lib/libm/src/s_conjf.c b/lib/libm/src/s_conjf.c new file mode 100644 index 00000000000..d5b765790c6 --- /dev/null +++ b/lib/libm/src/s_conjf.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_conjf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +float complex +conjf(float complex z) +{ + return ~z; +} diff --git a/lib/libm/src/s_cpow.c b/lib/libm/src/s_cpow.c new file mode 100644 index 00000000000..6b0537393ce --- /dev/null +++ b/lib/libm/src/s_cpow.c @@ -0,0 +1,71 @@ +/* $OpenBSD: s_cpow.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cpow + * + * Complex power function + * + * + * + * SYNOPSIS: + * + * double complex cpow(); + * double complex a, z, w; + * + * w = cpow (a, z); + * + * + * + * DESCRIPTION: + * + * Raises complex A to the complex Zth power. + * Definition is per AMS55 # 4.2.8, + * analytically equivalent to cpow(a,z) = cexp(z clog(a)). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.4e-15 1.5e-15 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +cpow(double complex a, double complex z) +{ + double complex w; + double x, y, r, theta, absa, arga; + + x = creal (z); + y = cimag (z); + absa = cabs (a); + if (absa == 0.0) { + return (0.0 + 0.0 * I); + } + arga = carg (a); + r = pow (absa, x); + theta = x * arga; + if (y != 0.0) { + r = r * exp (-y * arga); + theta = theta + y * log (absa); + } + w = r * cos (theta) + (r * sin (theta)) * I; + return (w); +} diff --git a/lib/libm/src/s_cpowf.c b/lib/libm/src/s_cpowf.c new file mode 100644 index 00000000000..8a24596d338 --- /dev/null +++ b/lib/libm/src/s_cpowf.c @@ -0,0 +1,71 @@ +/* $OpenBSD: s_cpowf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* cpowf + * + * Complex power function + * + * + * + * SYNOPSIS: + * + * float complex cpowf(); + * float complex a, z, w; + * + * w = cpowf (a, z); + * + * + * + * DESCRIPTION: + * + * Raises complex A to the complex Zth power. + * Definition is per AMS55 # 4.2.8, + * analytically equivalent to cpow(a,z) = cexp(z clog(a)). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 9.4e-15 1.5e-15 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +cpowf(float complex a, float complex z) +{ + float complex w; + float x, y, r, theta, absa, arga; + + x = creal (z); + y = cimag (z); + absa = cabsf (a); + if (absa == 0.0f) { + return (0.0f + 0.0f * I); + } + arga = cargf (a); + r = powf (absa, x); + theta = x * arga; + if (y != 0.0f) { + r = r * expf (-y * arga); + theta = theta + y * logf (absa); + } + w = r * cosf (theta) + (r * sinf (theta)) * I; + return (w); +} diff --git a/lib/libm/src/s_cproj.c b/lib/libm/src/s_cproj.c new file mode 100644 index 00000000000..7064e9285c3 --- /dev/null +++ b/lib/libm/src/s_cproj.c @@ -0,0 +1,32 @@ +/* $OpenBSD: s_cproj.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double complex +cproj(double complex z) +{ + double complex res; + + if (isinf(__real__ z) || isinf(__imag__ z)) { + __real__ res = INFINITY; + __imag__ res = copysign(0.0, __imag__ z); + } + + return res; +} diff --git a/lib/libm/src/s_cprojf.c b/lib/libm/src/s_cprojf.c new file mode 100644 index 00000000000..af754ed3d70 --- /dev/null +++ b/lib/libm/src/s_cprojf.c @@ -0,0 +1,32 @@ +/* $OpenBSD: s_cprojf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +float complex +cprojf(float complex z) +{ + float complex res; + + if (isinf(__real__ z) || isinf(__imag__ z)) { + __real__ res = INFINITY; + __imag__ res = copysign(0.0, __imag__ z); + } + + return res; +} diff --git a/lib/libm/src/s_creal.c b/lib/libm/src/s_creal.c new file mode 100644 index 00000000000..55c36e8d839 --- /dev/null +++ b/lib/libm/src/s_creal.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_creal.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +double +creal(double complex z) +{ + return __real__ z; +} diff --git a/lib/libm/src/s_crealf.c b/lib/libm/src/s_crealf.c new file mode 100644 index 00000000000..12c54ea615b --- /dev/null +++ b/lib/libm/src/s_crealf.c @@ -0,0 +1,25 @@ +/* $OpenBSD: s_crealf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <complex.h> +#include <math.h> + +float +crealf(float complex z) +{ + return __real__ z; +} diff --git a/lib/libm/src/s_csin.c b/lib/libm/src/s_csin.c new file mode 100644 index 00000000000..ad249de7ac0 --- /dev/null +++ b/lib/libm/src/s_csin.c @@ -0,0 +1,86 @@ +/* $OpenBSD: s_csin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csin() + * + * Complex circular sine + * + * + * + * SYNOPSIS: + * + * double complex csin(); + * double complex z, w; + * + * w = csin (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = sin x cosh y + i cos x sinh y. + * + * csin(z) = -i csinh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 8400 5.3e-17 1.3e-17 + * IEEE -10,+10 30000 3.8e-16 1.0e-16 + * Also tested by csin(casin(z)) = z. + * + */ + +#include <complex.h> +#include <math.h> + +/* calculate cosh and sinh */ + +static void +cchsh(double x, double *c, double *s) +{ + double e, ei; + + if (fabs(x) <= 0.5) { + *c = cosh(x); + *s = sinh(x); + } + else { + e = exp(x); + ei = 0.5/e; + e = 0.5 * e; + *s = e - ei; + *c = e + ei; + } +} + +double complex +csin(double complex z) +{ + double complex w; + double ch, sh; + + cchsh( cimag (z), &ch, &sh ); + w = sin (creal(z)) * ch + (cos (creal(z)) * sh) * I; + return (w); +} diff --git a/lib/libm/src/s_csinf.c b/lib/libm/src/s_csinf.c new file mode 100644 index 00000000000..aacc59f9dc6 --- /dev/null +++ b/lib/libm/src/s_csinf.c @@ -0,0 +1,85 @@ +/* $OpenBSD: s_csinf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csinf() + * + * Complex circular sine + * + * + * + * SYNOPSIS: + * + * void csinf(); + * cmplxf z, w; + * + * csinf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * w = sin x cosh y + i cos x sinh y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.9e-7 5.5e-8 + * + */ + +#include <complex.h> +#include <math.h> + +/* calculate cosh and sinh */ + +static void +cchshf(float xx, float *c, float *s) +{ + float x, e, ei; + + x = xx; + if(fabsf(x) <= 0.5f) { + *c = coshf(x); + *s = sinhf(x); + } + else { + e = expf(x); + ei = 0.5f/e; + e = 0.5f * e; + *s = e - ei; + *c = e + ei; + } +} + +float complex +csinf(float complex z) +{ + float complex w; + float ch, sh; + + cchshf((float) cimag(z), &ch, &sh); + w = sinf(creal(z)) * ch + (cosf(creal(z)) * sh) * I; + return (w); +} diff --git a/lib/libm/src/s_csinh.c b/lib/libm/src/s_csinh.c new file mode 100644 index 00000000000..ece633cda8f --- /dev/null +++ b/lib/libm/src/s_csinh.c @@ -0,0 +1,57 @@ +/* $OpenBSD: s_csinh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csinh + * + * Complex hyperbolic sine + * + * + * + * SYNOPSIS: + * + * double complex csinh(); + * double complex z, w; + * + * w = csinh (z); + * + * DESCRIPTION: + * + * csinh z = (cexp(z) - cexp(-z))/2 + * = sinh x * cos y + i cosh x * sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 3.1e-16 8.2e-17 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +csinh(double complex z) +{ + double complex w; + double x, y; + + x = creal(z); + y = cimag(z); + w = sinh (x) * cos (y) + (cosh (x) * sin (y)) * I; + return (w); +} diff --git a/lib/libm/src/s_csinhf.c b/lib/libm/src/s_csinhf.c new file mode 100644 index 00000000000..170b4405640 --- /dev/null +++ b/lib/libm/src/s_csinhf.c @@ -0,0 +1,57 @@ +/* $OpenBSD: s_csinhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csinhf + * + * Complex hyperbolic sine + * + * + * + * SYNOPSIS: + * + * float complex csinhf(); + * float complex z, w; + * + * w = csinhf (z); + * + * DESCRIPTION: + * + * csinh z = (cexp(z) - cexp(-z))/2 + * = sinh x * cos y + i cosh x * sin y . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 3.1e-16 8.2e-17 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +csinhf(float complex z) +{ + float complex w; + float x, y; + + x = creal(z); + y = cimag(z); + w = sinhf (x) * cosf (y) + (coshf (x) * sinf (y)) * I; + return (w); +} diff --git a/lib/libm/src/s_csqrt.c b/lib/libm/src/s_csqrt.c new file mode 100644 index 00000000000..3ed4aa56076 --- /dev/null +++ b/lib/libm/src/s_csqrt.c @@ -0,0 +1,131 @@ +/* $OpenBSD: s_csqrt.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csqrt() + * + * Complex square root + * + * + * + * SYNOPSIS: + * + * double complex csqrt(); + * double complex z, w; + * + * w = csqrt (z); + * + * + * + * DESCRIPTION: + * + * + * If z = x + iy, r = |z|, then + * + * 1/2 + * Re w = [ (r + x)/2 ] , + * + * 1/2 + * Im w = [ (r - x)/2 ] . + * + * Cancellation error in r-x or r+x is avoided by using the + * identity 2 Re w Im w = y. + * + * Note that -w is also a square root of z. The root chosen + * is always in the right half plane and Im w has the same sign as y. + * + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 25000 3.2e-17 9.6e-18 + * IEEE -10,+10 1,000,000 2.9e-16 6.1e-17 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +csqrt(double complex z) +{ + double complex w; + double x, y, r, t, scale; + + x = creal (z); + y = cimag (z); + + if (y == 0.0) { + if (x == 0.0) { + w = 0.0 + y * I; + } + else { + r = fabs (x); + r = sqrt (r); + if (x < 0.0) { + w = 0.0 + r * I; + } + else { + w = r + y * I; + } + } + return (w); + } + if (x == 0.0) { + r = fabs (y); + r = sqrt (0.5*r); + if (y > 0) + w = r + r * I; + else + w = r - r * I; + return (w); + } + /* Rescale to avoid internal overflow or underflow. */ + if ((fabs(x) > 4.0) || (fabs(y) > 4.0)) { + x *= 0.25; + y *= 0.25; + scale = 2.0; + } + else { + x *= 1.8014398509481984e16; /* 2^54 */ + y *= 1.8014398509481984e16; + scale = 7.450580596923828125e-9; /* 2^-27 */ +#if 0 + x *= 4.0; + y *= 4.0; + scale = 0.5; +#endif + } + w = x + y * I; + r = cabs(w); + if (x > 0) { + t = sqrt(0.5 * r + 0.5 * x); + r = scale * fabs((0.5 * y) / t); + t *= scale; + } + else { + r = sqrt( 0.5 * r - 0.5 * x ); + t = scale * fabs( (0.5 * y) / r ); + r *= scale; + } + if (y < 0) + w = t - r * I; + else + w = t + r * I; + return (w); +} diff --git a/lib/libm/src/s_csqrtf.c b/lib/libm/src/s_csqrtf.c new file mode 100644 index 00000000000..9f9e8982b0e --- /dev/null +++ b/lib/libm/src/s_csqrtf.c @@ -0,0 +1,131 @@ +/* $OpenBSD: s_csqrtf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* csqrtf() + * + * Complex square root + * + * + * + * SYNOPSIS: + * + * float complex csqrtf(); + * float complex z, w; + * + * w = csqrtf( z ); + * + * + * + * DESCRIPTION: + * + * + * If z = x + iy, r = |z|, then + * + * 1/2 + * Re w = [ (r + x)/2 ] , + * + * 1/2 + * Im w = [ (r - x)/2 ] . + * + * Cancellation error in r-x or r+x is avoided by using the + * identity 2 Re w Im w = y. + * + * Note that -w is also a square root of z. The root chosen + * is always in the right half plane and Im w has the same sign as y. + * + * + * + * ACCURACY: + * + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 1,000,000 1.8e-7 3.5e-8 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +csqrtf(float complex z) +{ + float complex w; + float x, y, r, t, scale; + + x = creal(z); + y = cimag(z); + + if(y == 0.0f) { + if (x < 0.0f) { + w = 0.0f + sqrtf(-x) * I; + return (w); + } + else if (x == 0.0f) { + return (0.0f + y * I); + } + else { + w = sqrtf(x) + y * I; + return (w); + } + } + + if (x == 0.0f) { + r = fabsf(y); + r = sqrtf(0.5f*r); + if(y > 0) + w = r + r * I; + else + w = r - r * I; + return (w); + } + + /* Rescale to avoid internal overflow or underflow. */ + if ((fabsf(x) > 4.0f) || (fabsf(y) > 4.0f)) { + x *= 0.25f; + y *= 0.25f; + scale = 2.0f; + } + else { + x *= 6.7108864e7f; /* 2^26 */ + y *= 6.7108864e7f; + scale = 1.220703125e-4f; /* 2^-13 */ +#if 0 + x *= 4.0f; + y *= 4.0f; + scale = 0.5f; +#endif + } + w = x + y * I; + r = cabsf(w); + if (x > 0) { + t = sqrtf( 0.5f * r + 0.5f * x ); + r = scale * fabsf((0.5f * y) / t); + t *= scale; + } + else { + r = sqrtf(0.5f * r - 0.5f * x); + t = scale * fabsf((0.5f * y) / r); + r *= scale; + } + + if (y < 0) + w = t - r * I; + else + w = t + r * I; + return (w); +} diff --git a/lib/libm/src/s_ctan.c b/lib/libm/src/s_ctan.c new file mode 100644 index 00000000000..4db6fb18e83 --- /dev/null +++ b/lib/libm/src/s_ctan.c @@ -0,0 +1,152 @@ +/* $OpenBSD: s_ctan.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ctan() + * + * Complex circular tangent + * + * + * + * SYNOPSIS: + * + * double complex ctan(); + * double complex z, w; + * + * w = ctan (z); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * sin 2x + i sinh 2y + * w = --------------------. + * cos 2x + cosh 2y + * + * On the real axis the denominator is zero at odd multiples + * of PI/2. The denominator is evaluated by its Taylor + * series near these points. + * + * ctan(z) = -i ctanh(iz). + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * DEC -10,+10 5200 7.1e-17 1.6e-17 + * IEEE -10,+10 30000 7.2e-16 1.2e-16 + * Also tested by ctan * ccot = 1 and catan(ctan(z)) = z. + */ + +#include <complex.h> +#include <math.h> + +#define MACHEP 1.1e-16 +#define MAXNUM 1.0e308 + +static const double DP1 = 3.14159265160560607910E0; +static const double DP2 = 1.98418714791870343106E-9; +static const double DP3 = 1.14423774522196636802E-17; + +static double +_redupi(double x) +{ + double t; + long i; + + t = x/M_PI; + if (t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return (t); +} + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static double +_ctans(double complex z) +{ + double f, x, x2, y, y2, rn, t; + double d; + + x = fabs (2.0 * creal (z)); + y = fabs (2.0 * cimag(z)); + + x = _redupi(x); + + x = x * x; + y = y * y; + x2 = 1.0; + y2 = 1.0; + f = 1.0; + rn = 0.0; + d = 0.0; + do { + rn += 1.0; + f *= rn; + rn += 1.0; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 + x2; + t /= f; + d += t; + + rn += 1.0; + f *= rn; + rn += 1.0; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 - x2; + t /= f; + d += t; + } + while (fabs(t/d) > MACHEP) + ; + return (d); +} + +double complex +ctan(double complex z) +{ + double complex w; + double d; + + d = cos (2.0 * creal (z)) + cosh (2.0 * cimag (z)); + + if (fabs(d) < 0.25) + d = _ctans (z); + + if (d == 0.0) { + /*mtherr ("ctan", OVERFLOW);*/ + w = MAXNUM + MAXNUM * I; + return (w); + } + + w = sin (2.0 * creal(z)) / d + (sinh (2.0 * cimag(z)) / d) * I; + return (w); +} diff --git a/lib/libm/src/s_ctanf.c b/lib/libm/src/s_ctanf.c new file mode 100644 index 00000000000..ca67d602e55 --- /dev/null +++ b/lib/libm/src/s_ctanf.c @@ -0,0 +1,148 @@ +/* $OpenBSD: s_ctanf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ctanf() + * + * Complex circular tangent + * + * + * + * SYNOPSIS: + * + * void ctanf(); + * cmplxf z, w; + * + * ctanf( &z, &w ); + * + * + * + * DESCRIPTION: + * + * If + * z = x + iy, + * + * then + * + * sin 2x + i sinh 2y + * w = --------------------. + * cos 2x + cosh 2y + * + * On the real axis the denominator is zero at odd multiples + * of PI/2. The denominator is evaluated by its Taylor + * series near these points. + * + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 3.3e-7 5.1e-8 + */ + +#include <complex.h> +#include <math.h> + +#define MACHEPF 3.0e-8 +#define MAXNUMF 1.0e38f + +static const double DP1 = 3.140625; +static const double DP2 = 9.67502593994140625E-4; +static const double DP3 = 1.509957990978376432E-7; + +static float +_redupif(float xx) +{ + float x, t; + long i; + + x = xx; + t = x/(float)M_PI; + if(t >= 0.0) + t += 0.5; + else + t -= 0.5; + + i = t; /* the multiple */ + t = i; + t = ((x - t * DP1) - t * DP2) - t * DP3; + return(t); +} + +/* Taylor series expansion for cosh(2y) - cos(2x) */ + +static float +_ctansf(float complex z) +{ + float f, x, x2, y, y2, rn, t, d; + + x = fabsf(2.0f * creal(z)); + y = fabsf(2.0f * cimag(z)); + + x = _redupif(x); + + x = x * x; + y = y * y; + x2 = 1.0f; + y2 = 1.0f; + f = 1.0f; + rn = 0.0f; + d = 0.0f; + do { + rn += 1.0f; + f *= rn; + rn += 1.0f; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 + x2; + t /= f; + d += t; + + rn += 1.0f; + f *= rn; + rn += 1.0f; + f *= rn; + x2 *= x; + y2 *= y; + t = y2 - x2; + t /= f; + d += t; + } + while (fabsf(t/d) > MACHEPF) + ; + return(d); +} + +float complex +ctanf(float complex z) +{ + float complex w; + float d; + + d = cosf( 2.0f * creal(z) ) + coshf( 2.0f * cimag(z) ); + + if(fabsf(d) < 0.25f) + d = _ctansf(z); + + if (d == 0.0f) { + /*mtherr( "ctanf", OVERFLOW );*/ + w = MAXNUMF + MAXNUMF * I; + return (w); + } + w = sinf (2.0f * creal(z)) / d + (sinhf (2.0f * cimag(z)) / d) * I; + return (w); +} diff --git a/lib/libm/src/s_ctanh.c b/lib/libm/src/s_ctanh.c new file mode 100644 index 00000000000..30c20155672 --- /dev/null +++ b/lib/libm/src/s_ctanh.c @@ -0,0 +1,59 @@ +/* $OpenBSD: s_ctanh.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ctanh + * + * Complex hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * double complex ctanh(); + * double complex z, w; + * + * w = ctanh (z); + * + * + * + * DESCRIPTION: + * + * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.7e-14 2.4e-16 + * + */ + +#include <complex.h> +#include <math.h> + +double complex +ctanh(double complex z) +{ + double complex w; + double x, y, d; + + x = creal(z); + y = cimag(z); + d = cosh (2.0 * x) + cos (2.0 * y); + w = sinh (2.0 * x) / d + (sin (2.0 * y) / d) * I; + return (w); +} diff --git a/lib/libm/src/s_ctanhf.c b/lib/libm/src/s_ctanhf.c new file mode 100644 index 00000000000..a0f61614452 --- /dev/null +++ b/lib/libm/src/s_ctanhf.c @@ -0,0 +1,59 @@ +/* $OpenBSD: s_ctanhf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/* + * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, 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. + */ + +/* ctanhf + * + * Complex hyperbolic tangent + * + * + * + * SYNOPSIS: + * + * float complex ctanhf(); + * float complex z, w; + * + * w = ctanhf (z); + * + * + * + * DESCRIPTION: + * + * tanh z = (sinh 2x + i sin 2y) / (cosh 2x + cos 2y) . + * + * ACCURACY: + * + * Relative error: + * arithmetic domain # trials peak rms + * IEEE -10,+10 30000 1.7e-14 2.4e-16 + * + */ + +#include <complex.h> +#include <math.h> + +float complex +ctanhf(float complex z) +{ + float complex w; + float x, y, d; + + x = creal(z); + y = cimag(z); + d = coshf (2.0f * x) + cosf (2.0f * y); + w = sinhf (2.0f * x) / d + (sinf (2.0f * y) / d) * I; + return (w); +} diff --git a/lib/libm/src/s_erf.c b/lib/libm/src/s_erf.c index 844e2f5565a..22944c1bc83 100644 --- a/lib/libm/src/s_erf.c +++ b/lib/libm/src/s_erf.c @@ -235,7 +235,7 @@ erf(double x) } z = x; SET_LOW_WORD(z,0); - r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); + r = exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S); if(hx>=0) return one-r/x; else return r/x-one; } @@ -293,8 +293,7 @@ erfc(double x) } z = x; SET_LOW_WORD(z,0); - r = __ieee754_exp(-z*z-0.5625)* - __ieee754_exp((z-x)*(z+x)+R/S); + r = exp(-z*z-0.5625) * exp((z-x)*(z+x)+R/S); if(hx>0) return r/x; else return two-r/x; } else { if(hx>0) return tiny*tiny; else return two-tiny; diff --git a/lib/libm/src/s_erff.c b/lib/libm/src/s_erff.c index faff192c21e..7eadb30dfa3 100644 --- a/lib/libm/src/s_erff.c +++ b/lib/libm/src/s_erff.c @@ -144,7 +144,7 @@ erff(float x) } GET_FLOAT_WORD(ix,x); SET_FLOAT_WORD(z,ix&0xfffff000); - r = __ieee754_expf(-z*z-(float)0.5625)*__ieee754_expf((z-x)*(z+x)+R/S); + r = expf(-z*z-(float)0.5625)*expf((z-x)*(z+x)+R/S); if(hx>=0) return one-r/x; else return r/x-one; } @@ -202,8 +202,7 @@ erfcf(float x) } GET_FLOAT_WORD(ix,x); SET_FLOAT_WORD(z,ix&0xfffff000); - r = __ieee754_expf(-z*z-(float)0.5625)* - __ieee754_expf((z-x)*(z+x)+R/S); + r = expf(-z*z-(float)0.5625) * expf((z-x)*(z+x)+R/S); if(hx>0) return r/x; else return two-r/x; } else { if(hx>0) return tiny*tiny; else return two-tiny; diff --git a/lib/libm/src/s_fdim.c b/lib/libm/src/s_fdim.c new file mode 100644 index 00000000000..6af4ba038b9 --- /dev/null +++ b/lib/libm/src/s_fdim.c @@ -0,0 +1,44 @@ +/* $OpenBSD: s_fdim.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/*- + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <math.h> + +#define DECL(type, fn) \ +type \ +fn(type x, type y) \ +{ \ + \ + if (isnan(x)) \ + return (x); \ + if (isnan(y)) \ + return (y); \ + return (x > y ? x - y : 0.0); \ +} + +DECL(double, fdim) +DECL(float, fdimf) +DECL(long double, fdiml) diff --git a/lib/libm/src/s_fmax.c b/lib/libm/src/s_fmax.c new file mode 100644 index 00000000000..76f91272f2c --- /dev/null +++ b/lib/libm/src/s_fmax.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_fmax.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/*- + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +double +fmax(double x, double y) +{ + struct ieee_double *px = (struct ieee_double *)&x; + struct ieee_double *py = (struct ieee_double *)&y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (px->dbl_exp == DBL_EXP_INFNAN && + (px->dbl_frach | px->dbl_fracl) != 0) + return (y); + if (py->dbl_exp == DBL_EXP_INFNAN && + (py->dbl_frach | py->dbl_fracl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (px->dbl_sign != py->dbl_sign && + px->dbl_sign == 1) + return (y); + if (px->dbl_sign != py->dbl_sign && + px->dbl_sign == 0) + return (x); + + return (x > y ? x : y); +} diff --git a/lib/libm/src/s_fmaxf.c b/lib/libm/src/s_fmaxf.c new file mode 100644 index 00000000000..472372950d8 --- /dev/null +++ b/lib/libm/src/s_fmaxf.c @@ -0,0 +1,51 @@ +/* $OpenBSD: s_fmaxf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/*- + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +float +fmaxf(float x, float y) +{ + struct ieee_single *px = (struct ieee_single *)&x; + struct ieee_single *py = (struct ieee_single *)&y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (px->sng_exp == SNG_EXP_INFNAN && px->sng_frac != 0) + return (y); + if (py->sng_exp == SNG_EXP_INFNAN && py->sng_frac != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (px->sng_sign != py->sng_sign && px->sng_sign == 1) + return (y); + if (px->sng_sign != py->sng_sign && px->sng_sign == 0) + return (x); + + return (x > y ? x : y); +} diff --git a/lib/libm/src/s_fmin.c b/lib/libm/src/s_fmin.c new file mode 100644 index 00000000000..47c5d9a67a9 --- /dev/null +++ b/lib/libm/src/s_fmin.c @@ -0,0 +1,55 @@ +/* $OpenBSD: s_fmin.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/*- + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +double +fmin(double x, double y) +{ + struct ieee_double *px = (struct ieee_double *)&x; + struct ieee_double *py = (struct ieee_double *)&y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (px->dbl_exp == DBL_EXP_INFNAN && + (px->dbl_frach | px->dbl_fracl) != 0) + return (y); + if (py->dbl_exp == DBL_EXP_INFNAN && + (py->dbl_frach | py->dbl_fracl) != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (px->dbl_sign != py->dbl_sign && + py->dbl_sign == 1) + return (y); + if (px->dbl_sign != py->dbl_sign && + py->dbl_sign == 0) + return (x); + + return (x < y ? x : y); +} diff --git a/lib/libm/src/s_fminf.c b/lib/libm/src/s_fminf.c new file mode 100644 index 00000000000..37de5c63e83 --- /dev/null +++ b/lib/libm/src/s_fminf.c @@ -0,0 +1,51 @@ +/* $OpenBSD: s_fminf.c,v 1.1 2008/09/07 20:36:09 martynas Exp $ */ +/*- + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <machine/ieee.h> +#include <math.h> + +float +fminf(float x, float y) +{ + struct ieee_single *px = (struct ieee_single *)&x; + struct ieee_single *py = (struct ieee_single *)&y; + + /* Check for NaNs to avoid raising spurious exceptions. */ + if (px->sng_exp == SNG_EXP_INFNAN && px->sng_frac != 0) + return (y); + if (py->sng_exp == SNG_EXP_INFNAN && py->sng_frac != 0) + return (x); + + /* Handle comparisons of signed zeroes. */ + if (px->sng_sign != py->sng_sign && py->sng_sign == 1) + return (y); + if (px->sng_sign != py->sng_sign && py->sng_sign == 0) + return (x); + + return (x < y ? x : y); +} diff --git a/lib/libm/src/s_lib_version.c b/lib/libm/src/s_lib_version.c deleted file mode 100644 index c4cfae37adb..00000000000 --- a/lib/libm/src/s_lib_version.c +++ /dev/null @@ -1,39 +0,0 @@ -/* @(#)s_lib_ver.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: s_lib_version.c,v 1.6 1995/05/10 20:47:44 jtc Exp $"; -#endif - -/* - * MACRO for standards - */ - -#include "math.h" -#include "math_private.h" - -/* - * define and initialize _LIB_VERSION - */ -#ifdef _POSIX_MODE -_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; -#else -#ifdef _XOPEN_MODE -_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; -#else -#ifdef _SVID3_MODE -_LIB_VERSION_TYPE _LIB_VERSION = _SVID_; -#else /* default _IEEE_MODE */ -_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_; -#endif -#endif -#endif diff --git a/lib/libm/src/s_matherr.c b/lib/libm/src/s_matherr.c deleted file mode 100644 index 9dfa8c7dd85..00000000000 --- a/lib/libm/src/s_matherr.c +++ /dev/null @@ -1,26 +0,0 @@ -/* @(#)s_matherr.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: s_matherr.c,v 1.6 1995/05/10 20:47:53 jtc Exp $"; -#endif - -#include "math.h" -#include "math_private.h" - -int -matherr(struct exception *x) -{ - int n=0; - if(x->arg1!=x->arg1) return 0; - return n; -} diff --git a/lib/libm/src/s_nan.c b/lib/libm/src/s_nan.c index f847545722c..3e99cfda129 100644 --- a/lib/libm/src/s_nan.c +++ b/lib/libm/src/s_nan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: s_nan.c,v 1.3 2008/08/08 00:41:17 martynas Exp $ */ +/* $OpenBSD: s_nan.c,v 1.4 2008/09/07 20:36:09 martynas Exp $ */ /*- * Copyright (c) 2007 David Schultz * All rights reserved. @@ -40,7 +40,7 @@ /* * OpenBSD's ctype doesn't have digittoint, so we define it here. */ -int +static int _digittoint(int c) { if (!isxdigit(c)) diff --git a/lib/libm/src/s_significand.c b/lib/libm/src/s_significand.c index 1751d59e72b..cf4faa24d04 100644 --- a/lib/libm/src/s_significand.c +++ b/lib/libm/src/s_significand.c @@ -26,5 +26,5 @@ static char rcsid[] = "$NetBSD: s_significand.c,v 1.6 1995/05/10 20:48:11 jtc Ex double significand(double x) { - return __ieee754_scalb(x,(double) -ilogb(x)); + return scalb(x,(double) -ilogb(x)); } diff --git a/lib/libm/src/s_significandf.c b/lib/libm/src/s_significandf.c index 5a7c0965475..085fabc93d2 100644 --- a/lib/libm/src/s_significandf.c +++ b/lib/libm/src/s_significandf.c @@ -23,5 +23,5 @@ static char rcsid[] = "$NetBSD: s_significandf.c,v 1.3 1995/05/10 20:48:13 jtc E float significandf(float x) { - return __ieee754_scalbf(x,(float) -ilogbf(x)); + return scalbf(x,(float) -ilogbf(x)); } diff --git a/lib/libm/src/w_acos.c b/lib/libm/src/w_acos.c deleted file mode 100644 index 142a6f9c076..00000000000 --- a/lib/libm/src/w_acos.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_acos.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_acos.c,v 1.6 1995/05/10 20:48:26 jtc Exp $"; -#endif - -/* - * wrap_acos(x) - */ - -#include "math.h" -#include "math_private.h" - -double -acos(double x) /* wrapper acos */ -{ -#ifdef _IEEE_LIBM - return __ieee754_acos(x); -#else - double z; - z = __ieee754_acos(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabs(x)>1.0) { - return __kernel_standard(x,x,1); /* acos(|x|>1) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_acosf.c b/lib/libm/src/w_acosf.c deleted file mode 100644 index ee56e6df6e4..00000000000 --- a/lib/libm/src/w_acosf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_acosf.c -- float version of w_acos.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_acosf.c,v 1.3 1995/05/10 20:48:29 jtc Exp $"; -#endif - -/* - * wrap_acosf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -acosf(float x) /* wrapper acosf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_acosf(x); -#else - float z; - z = __ieee754_acosf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(fabsf(x)>(float)1.0) { - /* acosf(|x|>1) */ - return (float)__kernel_standard((double)x,(double)x,101); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_acosh.c b/lib/libm/src/w_acosh.c deleted file mode 100644 index 545b77bd352..00000000000 --- a/lib/libm/src/w_acosh.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_acosh.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_acosh.c,v 1.6 1995/05/10 20:48:31 jtc Exp $"; -#endif - -/* - * wrapper acosh(x) - */ - -#include "math.h" -#include "math_private.h" - -double -acosh(double x) /* wrapper acosh */ -{ -#ifdef _IEEE_LIBM - return __ieee754_acosh(x); -#else - double z; - z = __ieee754_acosh(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<1.0) { - return __kernel_standard(x,x,29); /* acosh(x<1) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_acoshf.c b/lib/libm/src/w_acoshf.c deleted file mode 100644 index 62e48b0f15b..00000000000 --- a/lib/libm/src/w_acoshf.c +++ /dev/null @@ -1,43 +0,0 @@ -/* w_acoshf.c -- float version of w_acosh.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - * - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_acoshf.c,v 1.3 1995/05/10 20:48:33 jtc Exp $"; -#endif - -/* - * wrapper acoshf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -acoshf(float x) /* wrapper acoshf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_acoshf(x); -#else - float z; - z = __ieee754_acoshf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(x<(float)1.0) { - /* acosh(x<1) */ - return (float)__kernel_standard((double)x,(double)x,129); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_asin.c b/lib/libm/src/w_asin.c deleted file mode 100644 index f039e729f16..00000000000 --- a/lib/libm/src/w_asin.c +++ /dev/null @@ -1,39 +0,0 @@ -/* @(#)w_asin.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_asin.c,v 1.6 1995/05/10 20:48:35 jtc Exp $"; -#endif - -/* - * wrapper asin(x) - */ - - -#include "math.h" -#include "math_private.h" - -double -asin(double x) /* wrapper asin */ -{ -#ifdef _IEEE_LIBM - return __ieee754_asin(x); -#else - double z; - z = __ieee754_asin(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabs(x)>1.0) { - return __kernel_standard(x,x,2); /* asin(|x|>1) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_asinf.c b/lib/libm/src/w_asinf.c deleted file mode 100644 index 3d2c94d3c6c..00000000000 --- a/lib/libm/src/w_asinf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_asinf.c -- float version of w_asin.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_asinf.c,v 1.3 1995/05/10 20:48:37 jtc Exp $"; -#endif - -/* - * wrapper asinf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -asinf(float x) /* wrapper asinf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_asinf(x); -#else - float z; - z = __ieee754_asinf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(fabsf(x)>(float)1.0) { - /* asinf(|x|>1) */ - return (float)__kernel_standard((double)x,(double)x,102); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_atan2.c b/lib/libm/src/w_atan2.c deleted file mode 100644 index 135836af5b2..00000000000 --- a/lib/libm/src/w_atan2.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_atan2.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_atan2.c,v 1.6 1995/05/10 20:48:39 jtc Exp $"; -#endif - -/* - * wrapper atan2(y,x) - */ - -#include "math.h" -#include "math_private.h" - -double -atan2(double y, double x) /* wrapper atan2 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_atan2(y,x); -#else - double z; - z = __ieee754_atan2(y,x); - if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z; - if(x==0.0&&y==0.0) { - return __kernel_standard(y,x,3); /* atan2(+-0,+-0) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_atan2f.c b/lib/libm/src/w_atan2f.c deleted file mode 100644 index a1c9763b0ad..00000000000 --- a/lib/libm/src/w_atan2f.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_atan2f.c -- float version of w_atan2.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_atan2f.c,v 1.3 1995/05/10 20:48:42 jtc Exp $"; -#endif - -/* - * wrapper atan2f(y,x) - */ - -#include "math.h" -#include "math_private.h" - -float -atan2f(float y, float x) /* wrapper atan2f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_atan2f(y,x); -#else - float z; - z = __ieee754_atan2f(y,x); - if(_LIB_VERSION == _IEEE_||isnanf(x)||isnanf(y)) return z; - if(x==(float)0.0&&y==(float)0.0) { - /* atan2f(+-0,+-0) */ - return (float)__kernel_standard((double)y,(double)x,103); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_atanh.c b/lib/libm/src/w_atanh.c deleted file mode 100644 index 29cd574c018..00000000000 --- a/lib/libm/src/w_atanh.c +++ /dev/null @@ -1,42 +0,0 @@ -/* @(#)w_atanh.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_atanh.c,v 1.6 1995/05/10 20:48:43 jtc Exp $"; -#endif - -/* - * wrapper atanh(x) - */ - -#include "math.h" -#include "math_private.h" - -double -atanh(double x) /* wrapper atanh */ -{ -#ifdef _IEEE_LIBM - return __ieee754_atanh(x); -#else - double z,y; - z = __ieee754_atanh(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - y = fabs(x); - if(y>=1.0) { - if(y>1.0) - return __kernel_standard(x,x,30); /* atanh(|x|>1) */ - else - return __kernel_standard(x,x,31); /* atanh(|x|==1) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_atanhf.c b/lib/libm/src/w_atanhf.c deleted file mode 100644 index f33d64ebe62..00000000000 --- a/lib/libm/src/w_atanhf.c +++ /dev/null @@ -1,47 +0,0 @@ -/* w_atanhf.c -- float version of w_atanh.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_atanhf.c,v 1.3 1995/05/10 20:48:45 jtc Exp $"; -#endif - -/* - * wrapper atanhf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -atanhf(float x) /* wrapper atanhf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_atanhf(x); -#else - float z,y; - z = __ieee754_atanhf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - y = fabsf(x); - if(y>=(float)1.0) { - if(y>(float)1.0) - /* atanhf(|x|>1) */ - return (float)__kernel_standard((double)x,(double)x,130); - else - /* atanhf(|x|==1) */ - return (float)__kernel_standard((double)x,(double)x,131); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_cabs.c b/lib/libm/src/w_cabs.c deleted file mode 100644 index d851d339e58..00000000000 --- a/lib/libm/src/w_cabs.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * cabs() wrapper for hypot(). - * - * Written by J.T. Conklin, <jtc@wimsey.com> - * Placed into the Public Domain, 1994. - */ - -#include <math.h> - -struct complex { - double x; - double y; -}; - -double -cabs(struct complex z) -{ - return hypot(z.x, z.y); -} diff --git a/lib/libm/src/w_cabsf.c b/lib/libm/src/w_cabsf.c deleted file mode 100644 index d98d0422f28..00000000000 --- a/lib/libm/src/w_cabsf.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * cabsf() wrapper for hypotf(). - * - * Written by J.T. Conklin, <jtc@wimsey.com> - * Placed into the Public Domain, 1994. - */ - -#include "math.h" -#include "math_private.h" - -struct complex { - float x; - float y; -}; - -float -cabsf(struct complex z) -{ - return hypotf(z.x, z.y); -} diff --git a/lib/libm/src/w_cosh.c b/lib/libm/src/w_cosh.c deleted file mode 100644 index 4eb375f6ec1..00000000000 --- a/lib/libm/src/w_cosh.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_cosh.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_cosh.c,v 1.6 1995/05/10 20:48:47 jtc Exp $"; -#endif - -/* - * wrapper cosh(x) - */ - -#include "math.h" -#include "math_private.h" - -double -cosh(double x) /* wrapper cosh */ -{ -#ifdef _IEEE_LIBM - return __ieee754_cosh(x); -#else - double z; - z = __ieee754_cosh(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabs(x)>7.10475860073943863426e+02) { - return __kernel_standard(x,x,5); /* cosh overflow */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_coshf.c b/lib/libm/src/w_coshf.c deleted file mode 100644 index df7915d1e72..00000000000 --- a/lib/libm/src/w_coshf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_coshf.c -- float version of w_cosh.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_coshf.c,v 1.3 1995/05/10 20:48:49 jtc Exp $"; -#endif - -/* - * wrapper coshf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -coshf(float x) /* wrapper coshf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_coshf(x); -#else - float z; - z = __ieee754_coshf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(fabsf(x)>(float)8.9415985107e+01) { - /* cosh overflow */ - return (float)__kernel_standard((double)x,(double)x,105); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_exp.c b/lib/libm/src/w_exp.c deleted file mode 100644 index 655b438ca96..00000000000 --- a/lib/libm/src/w_exp.c +++ /dev/null @@ -1,45 +0,0 @@ -/* @(#)w_exp.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_exp.c,v 1.6 1995/05/10 20:48:51 jtc Exp $"; -#endif - -/* - * wrapper exp(x) - */ - -#include "math.h" -#include "math_private.h" - -static const double -o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ -u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ - -double -exp(double x) /* wrapper exp */ -{ -#ifdef _IEEE_LIBM - return __ieee754_exp(x); -#else - double z; - z = __ieee754_exp(x); - if(_LIB_VERSION == _IEEE_) return z; - if(finite(x)) { - if(x>o_threshold) - return __kernel_standard(x,x,6); /* exp overflow */ - else if(x<u_threshold) - return __kernel_standard(x,x,7); /* exp underflow */ - } - return z; -#endif -} diff --git a/lib/libm/src/w_expf.c b/lib/libm/src/w_expf.c deleted file mode 100644 index f11948b4e74..00000000000 --- a/lib/libm/src/w_expf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* w_expf.c -- float version of w_exp.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_expf.c,v 1.3 1995/05/10 20:48:53 jtc Exp $"; -#endif - -/* - * wrapper expf(x) - */ - -#include "math.h" -#include "math_private.h" - -static const float -o_threshold= 8.8721679688e+01, /* 0x42b17180 */ -u_threshold= -1.0397208405e+02; /* 0xc2cff1b5 */ - -float -expf(float x) /* wrapper expf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_expf(x); -#else - float z; - z = __ieee754_expf(x); - if(_LIB_VERSION == _IEEE_) return z; - if(finitef(x)) { - if(x>o_threshold) - /* exp overflow */ - return (float)__kernel_standard((double)x,(double)x,106); - else if(x<u_threshold) - /* exp underflow */ - return (float)__kernel_standard((double)x,(double)x,107); - } - return z; -#endif -} diff --git a/lib/libm/src/w_fmod.c b/lib/libm/src/w_fmod.c deleted file mode 100644 index 1f1504c13d5..00000000000 --- a/lib/libm/src/w_fmod.c +++ /dev/null @@ -1,39 +0,0 @@ -/* @(#)w_fmod.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_fmod.c,v 1.6 1995/05/10 20:48:55 jtc Exp $"; -#endif - -/* - * wrapper fmod(x,y) - */ - -#include "math.h" -#include "math_private.h" - - -double -fmod(double x, double y) /* wrapper fmod */ -{ -#ifdef _IEEE_LIBM - return __ieee754_fmod(x,y); -#else - double z; - z = __ieee754_fmod(x,y); - if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z; - if(y==0.0) { - return __kernel_standard(x,y,27); /* fmod(x,0) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_fmodf.c b/lib/libm/src/w_fmodf.c deleted file mode 100644 index c0deb804aba..00000000000 --- a/lib/libm/src/w_fmodf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_fmodf.c -- float version of w_fmod.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_fmodf.c,v 1.3 1995/05/10 20:48:57 jtc Exp $"; -#endif - -/* - * wrapper fmodf(x,y) - */ - -#include "math.h" -#include "math_private.h" - -float -fmodf(float x, float y) /* wrapper fmodf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_fmodf(x,y); -#else - float z; - z = __ieee754_fmodf(x,y); - if(_LIB_VERSION == _IEEE_ ||isnanf(y)||isnanf(x)) return z; - if(y==(float)0.0) { - /* fmodf(x,0) */ - return (float)__kernel_standard((double)x,(double)y,127); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_gamma.c b/lib/libm/src/w_gamma.c index baa7c711248..92112add553 100644 --- a/lib/libm/src/w_gamma.c +++ b/lib/libm/src/w_gamma.c @@ -28,18 +28,5 @@ extern int signgam; double gamma(double x) { -#ifdef _IEEE_LIBM - return __ieee754_lgamma_r(x,&signgam); -#else - double y; - y = __ieee754_lgamma_r(x,&signgam); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - if(floor(x)==x&&x<=0.0) - return __kernel_standard(x,x,41); /* gamma pole */ - else - return __kernel_standard(x,x,40); /* gamma overflow */ - } else - return y; -#endif + return lgamma_r(x,&signgam); } diff --git a/lib/libm/src/w_gamma_r.c b/lib/libm/src/w_gamma_r.c index 8157923f203..dcefb1f4832 100644 --- a/lib/libm/src/w_gamma_r.c +++ b/lib/libm/src/w_gamma_r.c @@ -24,18 +24,5 @@ static char rcsid[] = "$NetBSD: w_gamma_r.c,v 1.7 1995/11/20 22:06:45 jtc Exp $" double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */ { -#ifdef _IEEE_LIBM - return __ieee754_lgamma_r(x,signgamp); -#else - double y; - y = __ieee754_lgamma_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - if(floor(x)==x&&x<=0.0) - return __kernel_standard(x,x,41); /* gamma pole */ - else - return __kernel_standard(x,x,40); /* gamma overflow */ - } else - return y; -#endif + return lgamma_r(x,signgamp); } diff --git a/lib/libm/src/w_gammaf.c b/lib/libm/src/w_gammaf.c deleted file mode 100644 index cf668d2bf10..00000000000 --- a/lib/libm/src/w_gammaf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* w_gammaf.c -- float version of w_gamma.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_gammaf.c,v 1.4 1995/11/20 22:06:48 jtc Exp $"; -#endif - -#include "math.h" -#include "math_private.h" - -extern int signgam; - -float -gammaf(float x) -{ -#ifdef _IEEE_LIBM - return __ieee754_lgammaf_r(x,&signgam); -#else - float y; - y = __ieee754_lgammaf_r(x,&signgam); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - if(floorf(x)==x&&x<=(float)0.0) - /* gammaf pole */ - return (float)__kernel_standard((double)x,(double)x,141); - else - /* gammaf overflow */ - return (float)__kernel_standard((double)x,(double)x,140); - } else - return y; -#endif -} diff --git a/lib/libm/src/w_gammaf_r.c b/lib/libm/src/w_gammaf_r.c deleted file mode 100644 index 16f4b43b17f..00000000000 --- a/lib/libm/src/w_gammaf_r.c +++ /dev/null @@ -1,46 +0,0 @@ -/* w_gammaf_r.c -- float version of w_gamma_r.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_gammaf_r.c,v 1.4 1995/11/20 22:06:50 jtc Exp $"; -#endif - -/* - * wrapper float gammaf_r(float x, int *signgamp) - */ - -#include "math.h" -#include "math_private.h" - -float -gammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */ -{ -#ifdef _IEEE_LIBM - return __ieee754_lgammaf_r(x,signgamp); -#else - float y; - y = __ieee754_lgammaf_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - if(floorf(x)==x&&x<=(float)0.0) - /* gammaf pole */ - return (float)__kernel_standard((double)x,(double)x,141); - else - /* gamma overflow */ - return (float)__kernel_standard((double)x,(double)x,140); - } else - return y; -#endif -} diff --git a/lib/libm/src/w_hypot.c b/lib/libm/src/w_hypot.c deleted file mode 100644 index 57bdf938dbe..00000000000 --- a/lib/libm/src/w_hypot.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_hypot.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_hypot.c,v 1.6 1995/05/10 20:49:07 jtc Exp $"; -#endif - -/* - * wrapper hypot(x,y) - */ - -#include "math.h" -#include "math_private.h" - -double -hypot(double x, double y)/* wrapper hypot */ -{ -#ifdef _IEEE_LIBM - return __ieee754_hypot(x,y); -#else - double z; - z = __ieee754_hypot(x,y); - if(_LIB_VERSION == _IEEE_) return z; - if((!finite(z))&&finite(x)&&finite(y)) - return __kernel_standard(x,y,4); /* hypot overflow */ - else - return z; -#endif -} diff --git a/lib/libm/src/w_hypotf.c b/lib/libm/src/w_hypotf.c deleted file mode 100644 index d0f83fc7115..00000000000 --- a/lib/libm/src/w_hypotf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_hypotf.c -- float version of w_hypot.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_hypotf.c,v 1.3 1995/05/10 20:49:09 jtc Exp $"; -#endif - -/* - * wrapper hypotf(x,y) - */ - -#include "math.h" -#include "math_private.h" - -float -hypotf(float x, float y) /* wrapper hypotf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_hypotf(x,y); -#else - float z; - z = __ieee754_hypotf(x,y); - if(_LIB_VERSION == _IEEE_) return z; - if((!finitef(z))&&finitef(x)&&finitef(y)) - /* hypot overflow */ - return (float)__kernel_standard((double)x,(double)y,104); - else - return z; -#endif -} diff --git a/lib/libm/src/w_j0.c b/lib/libm/src/w_j0.c deleted file mode 100644 index 6e617427920..00000000000 --- a/lib/libm/src/w_j0.c +++ /dev/null @@ -1,61 +0,0 @@ -/* @(#)w_j0.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_j0.c,v 1.6 1995/05/10 20:49:11 jtc Exp $"; -#endif - -/* - * wrapper j0(double x), y0(double x) - */ - -#include "math.h" -#include "math_private.h" - -double -j0(double x) /* wrapper j0 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_j0(x); -#else - double z = __ieee754_j0(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(fabs(x)>X_TLOSS) { - return __kernel_standard(x,x,34); /* j0(|x|>X_TLOSS) */ - } else - return z; -#endif -} - -double -y0(double x) /* wrapper y0 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_y0(x); -#else - double z; - z = __ieee754_y0(x); - if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(x <= 0.0){ - if(x==0.0) - /* d= -one/(x-x); */ - return __kernel_standard(x,x,8); - else - /* d = zero/(x-x); */ - return __kernel_standard(x,x,9); - } - if(x>X_TLOSS) { - return __kernel_standard(x,x,35); /* y0(x>X_TLOSS) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_j0f.c b/lib/libm/src/w_j0f.c deleted file mode 100644 index 93ec42b366a..00000000000 --- a/lib/libm/src/w_j0f.c +++ /dev/null @@ -1,66 +0,0 @@ -/* w_j0f.c -- float version of w_j0.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_j0f.c,v 1.3 1995/05/10 20:49:13 jtc Exp $"; -#endif - -/* - * wrapper j0f(float x), y0f(float x) - */ - -#include "math.h" -#include "math_private.h" - -float -j0f(float x) /* wrapper j0f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_j0f(x); -#else - float z = __ieee754_j0f(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(fabsf(x)>(float)X_TLOSS) { - /* j0f(|x|>X_TLOSS) */ - return (float)__kernel_standard((double)x,(double)x,134); - } else - return z; -#endif -} - -float -y0f(float x) /* wrapper y0f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_y0f(x); -#else - float z; - z = __ieee754_y0f(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(x <= (float)0.0){ - if(x==(float)0.0) - /* d= -one/(x-x); */ - return (float)__kernel_standard((double)x,(double)x,108); - else - /* d = zero/(x-x); */ - return (float)__kernel_standard((double)x,(double)x,109); - } - if(x>(float)X_TLOSS) { - /* y0(x>X_TLOSS) */ - return (float)__kernel_standard((double)x,(double)x,135); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_j1.c b/lib/libm/src/w_j1.c deleted file mode 100644 index 23ca8befaf6..00000000000 --- a/lib/libm/src/w_j1.c +++ /dev/null @@ -1,62 +0,0 @@ -/* @(#)w_j1.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_j1.c,v 1.6 1995/05/10 20:49:15 jtc Exp $"; -#endif - -/* - * wrapper of j1,y1 - */ - -#include "math.h" -#include "math_private.h" - -double -j1(double x) /* wrapper j1 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_j1(x); -#else - double z; - z = __ieee754_j1(x); - if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(fabs(x)>X_TLOSS) { - return __kernel_standard(x,x,36); /* j1(|x|>X_TLOSS) */ - } else - return z; -#endif -} - -double -y1(double x) /* wrapper y1 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_y1(x); -#else - double z; - z = __ieee754_y1(x); - if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(x <= 0.0){ - if(x==0.0) - /* d= -one/(x-x); */ - return __kernel_standard(x,x,10); - else - /* d = zero/(x-x); */ - return __kernel_standard(x,x,11); - } - if(x>X_TLOSS) { - return __kernel_standard(x,x,37); /* y1(x>X_TLOSS) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_j1f.c b/lib/libm/src/w_j1f.c deleted file mode 100644 index 770c9ceab61..00000000000 --- a/lib/libm/src/w_j1f.c +++ /dev/null @@ -1,67 +0,0 @@ -/* w_j1f.c -- float version of w_j1.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_j1f.c,v 1.3 1995/05/10 20:49:17 jtc Exp $"; -#endif - -/* - * wrapper of j1f,y1f - */ - -#include "math.h" -#include "math_private.h" - -float -j1f(float x) /* wrapper j1f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_j1f(x); -#else - float z; - z = __ieee754_j1f(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(fabsf(x)>(float)X_TLOSS) { - /* j1(|x|>X_TLOSS) */ - return (float)__kernel_standard((double)x,(double)x,136); - } else - return z; -#endif -} - -float -y1f(float x) /* wrapper y1f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_y1f(x); -#else - float z; - z = __ieee754_y1f(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(x <= (float)0.0){ - if(x==(float)0.0) - /* d= -one/(x-x); */ - return (float)__kernel_standard((double)x,(double)x,110); - else - /* d = zero/(x-x); */ - return (float)__kernel_standard((double)x,(double)x,111); - } - if(x>(float)X_TLOSS) { - /* y1(x>X_TLOSS) */ - return (float)__kernel_standard((double)x,(double)x,137); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_jn.c b/lib/libm/src/w_jn.c deleted file mode 100644 index 2ea879e0bf3..00000000000 --- a/lib/libm/src/w_jn.c +++ /dev/null @@ -1,84 +0,0 @@ -/* @(#)w_jn.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_jn.c,v 1.6 1995/05/10 20:49:19 jtc Exp $"; -#endif - -/* - * wrapper jn(int n, double x), yn(int n, double x) - * floating point Bessel's function of the 1st and 2nd kind - * of order n - * - * Special cases: - * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; - * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. - * Note 2. About jn(n,x), yn(n,x) - * For n=0, j0(x) is called, - * for n=1, j1(x) is called, - * for n<x, forward recursion us used starting - * from values of j0(x) and j1(x). - * for n>x, a continued fraction approximation to - * j(n,x)/j(n-1,x) is evaluated and then backward - * recursion is used starting from a supposed value - * for j(n,x). The resulting value of j(0,x) is - * compared with the actual value to correct the - * supposed value of j(n,x). - * - * yn(n,x) is similar in all respects, except - * that forward recursion is used for all - * values of n>1. - * - */ - -#include "math.h" -#include "math_private.h" - -double -jn(int n, double x) /* wrapper jn */ -{ -#ifdef _IEEE_LIBM - return __ieee754_jn(n,x); -#else - double z; - z = __ieee754_jn(n,x); - if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(fabs(x)>X_TLOSS) { - return __kernel_standard((double)n,x,38); /* jn(|x|>X_TLOSS,n) */ - } else - return z; -#endif -} - -double -yn(int n, double x) /* wrapper yn */ -{ -#ifdef _IEEE_LIBM - return __ieee754_yn(n,x); -#else - double z; - z = __ieee754_yn(n,x); - if(_LIB_VERSION == _IEEE_ || isnan(x) ) return z; - if(x <= 0.0){ - if(x==0.0) - /* d= -one/(x-x); */ - return __kernel_standard((double)n,x,12); - else - /* d = zero/(x-x); */ - return __kernel_standard((double)n,x,13); - } - if(x>X_TLOSS) { - return __kernel_standard((double)n,x,39); /* yn(x>X_TLOSS,n) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_jnf.c b/lib/libm/src/w_jnf.c deleted file mode 100644 index a45f3b878f5..00000000000 --- a/lib/libm/src/w_jnf.c +++ /dev/null @@ -1,63 +0,0 @@ -/* w_jnf.c -- float version of w_jn.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_jnf.c,v 1.3 1995/05/10 20:49:21 jtc Exp $"; -#endif - -#include "math.h" -#include "math_private.h" - -float -jnf(int n, float x) /* wrapper jnf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_jnf(n,x); -#else - float z; - z = __ieee754_jnf(n,x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(fabsf(x)>(float)X_TLOSS) { - /* jn(|x|>X_TLOSS,n) */ - return (float)__kernel_standard((double)n,(double)x,138); - } else - return z; -#endif -} - -float -ynf(int n, float x) /* wrapper ynf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_ynf(n,x); -#else - float z; - z = __ieee754_ynf(n,x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) ) return z; - if(x <= (float)0.0){ - if(x==(float)0.0) - /* d= -one/(x-x); */ - return (float)__kernel_standard((double)n,(double)x,112); - else - /* d = zero/(x-x); */ - return (float)__kernel_standard((double)n,(double)x,113); - } - if(x>(float)X_TLOSS) { - /* yn(x>X_TLOSS,n) */ - return (float)__kernel_standard((double)n,(double)x,139); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_lgamma.c b/lib/libm/src/w_lgamma.c deleted file mode 100644 index 055fdb774fa..00000000000 --- a/lib/libm/src/w_lgamma.c +++ /dev/null @@ -1,45 +0,0 @@ -/* @(#)w_lgamma.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_lgamma.c,v 1.6 1995/05/10 20:49:24 jtc Exp $"; -#endif - -/* double lgamma(double x) - * Return the logarithm of the Gamma function of x. - * - * Method: call __ieee754_lgamma_r - */ - -#include "math.h" -#include "math_private.h" - -extern int signgam; - -double -lgamma(double x) -{ -#ifdef _IEEE_LIBM - return __ieee754_lgamma_r(x,&signgam); -#else - double y; - y = __ieee754_lgamma_r(x,&signgam); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - if(floor(x)==x&&x<=0.0) - return __kernel_standard(x,x,15); /* lgamma pole */ - else - return __kernel_standard(x,x,14); /* lgamma overflow */ - } else - return y; -#endif -} diff --git a/lib/libm/src/w_lgamma_r.c b/lib/libm/src/w_lgamma_r.c deleted file mode 100644 index 5e9d69ce239..00000000000 --- a/lib/libm/src/w_lgamma_r.c +++ /dev/null @@ -1,42 +0,0 @@ -/* @(#)wr_lgamma.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_lgamma_r.c,v 1.6 1995/05/10 20:49:27 jtc Exp $"; -#endif - -/* - * wrapper double lgamma_r(double x, int *signgamp) - */ - -#include "math.h" -#include "math_private.h" - - -double -lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */ -{ -#ifdef _IEEE_LIBM - return __ieee754_lgamma_r(x,signgamp); -#else - double y; - y = __ieee754_lgamma_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - if(floor(x)==x&&x<=0.0) - return __kernel_standard(x,x,15); /* lgamma pole */ - else - return __kernel_standard(x,x,14); /* lgamma overflow */ - } else - return y; -#endif -} diff --git a/lib/libm/src/w_lgammaf.c b/lib/libm/src/w_lgammaf.c deleted file mode 100644 index 0ec7716761f..00000000000 --- a/lib/libm/src/w_lgammaf.c +++ /dev/null @@ -1,44 +0,0 @@ -/* w_lgammaf.c -- float version of w_lgamma.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_lgammaf.c,v 1.3 1995/05/10 20:49:30 jtc Exp $"; -#endif - -#include "math.h" -#include "math_private.h" - -extern int signgam; - -float -lgammaf(float x) -{ -#ifdef _IEEE_LIBM - return __ieee754_lgammaf_r(x,&signgam); -#else - float y; - y = __ieee754_lgammaf_r(x,&signgam); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - if(floorf(x)==x&&x<=(float)0.0) - /* lgamma pole */ - return (float)__kernel_standard((double)x,(double)x,115); - else - /* lgamma overflow */ - return (float)__kernel_standard((double)x,(double)x,114); - } else - return y; -#endif -} diff --git a/lib/libm/src/w_lgammaf_r.c b/lib/libm/src/w_lgammaf_r.c deleted file mode 100644 index 49973d3637d..00000000000 --- a/lib/libm/src/w_lgammaf_r.c +++ /dev/null @@ -1,47 +0,0 @@ -/* w_lgammaf_r.c -- float version of w_lgamma_r.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_lgammaf_r.c,v 1.3 1995/05/10 20:49:32 jtc Exp $"; -#endif - -/* - * wrapper float lgammaf_r(float x, int *signgamp) - */ - -#include "math.h" -#include "math_private.h" - - -float -lgammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */ -{ -#ifdef _IEEE_LIBM - return __ieee754_lgammaf_r(x,signgamp); -#else - float y; - y = __ieee754_lgammaf_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - if(floorf(x)==x&&x<=(float)0.0) - /* lgamma pole */ - return (float)__kernel_standard((double)x,(double)x,115); - else - /* lgamma overflow */ - return (float)__kernel_standard((double)x,(double)x,114); - } else - return y; -#endif -} diff --git a/lib/libm/src/w_log.c b/lib/libm/src/w_log.c deleted file mode 100644 index b4dcdef1f05..00000000000 --- a/lib/libm/src/w_log.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_log.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_log.c,v 1.6 1995/05/10 20:49:33 jtc Exp $"; -#endif - -/* - * wrapper log(x) - */ - -#include "math.h" -#include "math_private.h" - -double -log(double x) /* wrapper log */ -{ -#ifdef _IEEE_LIBM - return __ieee754_log(x); -#else - double z; - z = __ieee754_log(x); - if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; - if(x==0.0) - return __kernel_standard(x,x,16); /* log(0) */ - else - return __kernel_standard(x,x,17); /* log(x<0) */ -#endif -} diff --git a/lib/libm/src/w_log10.c b/lib/libm/src/w_log10.c deleted file mode 100644 index f0b4e7c1740..00000000000 --- a/lib/libm/src/w_log10.c +++ /dev/null @@ -1,41 +0,0 @@ -/* @(#)w_log10.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_log10.c,v 1.6 1995/05/10 20:49:35 jtc Exp $"; -#endif - -/* - * wrapper log10(X) - */ - -#include "math.h" -#include "math_private.h" - -double -log10(double x) /* wrapper log10 */ -{ -#ifdef _IEEE_LIBM - return __ieee754_log10(x); -#else - double z; - z = __ieee754_log10(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<=0.0) { - if(x==0.0) - return __kernel_standard(x,x,18); /* log10(0) */ - else - return __kernel_standard(x,x,19); /* log10(x<0) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_log10f.c b/lib/libm/src/w_log10f.c deleted file mode 100644 index 4907438d820..00000000000 --- a/lib/libm/src/w_log10f.c +++ /dev/null @@ -1,46 +0,0 @@ -/* w_log10f.c -- float version of w_log10.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_log10f.c,v 1.3 1995/05/10 20:49:37 jtc Exp $"; -#endif - -/* - * wrapper log10f(X) - */ - -#include "math.h" -#include "math_private.h" - -float -log10f(float x) /* wrapper log10f */ -{ -#ifdef _IEEE_LIBM - return __ieee754_log10f(x); -#else - float z; - z = __ieee754_log10f(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(x<=(float)0.0) { - if(x==(float)0.0) - /* log10(0) */ - return (float)__kernel_standard((double)x,(double)x,118); - else - /* log10(x<0) */ - return (float)__kernel_standard((double)x,(double)x,119); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_logf.c b/lib/libm/src/w_logf.c deleted file mode 100644 index 5db12a6beaa..00000000000 --- a/lib/libm/src/w_logf.c +++ /dev/null @@ -1,43 +0,0 @@ -/* w_logf.c -- float version of w_log.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_logf.c,v 1.3 1995/05/10 20:49:40 jtc Exp $"; -#endif - -/* - * wrapper logf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -logf(float x) /* wrapper logf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_logf(x); -#else - float z; - z = __ieee754_logf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x) || x > (float)0.0) return z; - if(x==(float)0.0) - /* logf(0) */ - return (float)__kernel_standard((double)x,(double)x,116); - else - /* logf(x<0) */ - return (float)__kernel_standard((double)x,(double)x,117); -#endif -} diff --git a/lib/libm/src/w_pow.c b/lib/libm/src/w_pow.c deleted file mode 100644 index d1bf6374b9c..00000000000 --- a/lib/libm/src/w_pow.c +++ /dev/null @@ -1,56 +0,0 @@ - - -/* @(#)w_pow.c 5.2 93/10/01 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * wrapper pow(x,y) return x**y - */ - -#include "math.h" -#include "math_private.h" - -double -pow(double x, double y) /* wrapper pow */ -{ -#ifdef _IEEE_LIBM - return __ieee754_pow(x,y); -#else - double z; - z=__ieee754_pow(x,y); - if(_LIB_VERSION == _IEEE_|| isnan(y)) return z; - if(isnan(x)) { - if(y==0.0) - return __kernel_standard(x,y,42); /* pow(NaN,0.0) */ - else - return z; - } - if(x==0.0){ - if(y==0.0) - return __kernel_standard(x,y,20); /* pow(0.0,0.0) */ - if(finite(y)&&y<0.0) - return __kernel_standard(x,y,23); /* pow(0.0,negative) */ - return z; - } - if(!finite(z)) { - if(finite(x)&&finite(y)) { - if(isnan(z)) - return __kernel_standard(x,y,24); /* pow neg**non-int */ - else - return __kernel_standard(x,y,21); /* pow overflow */ - } - } - if(z==0.0&&finite(x)&&finite(y)) - return __kernel_standard(x,y,22); /* pow underflow */ - return z; -#endif -} diff --git a/lib/libm/src/w_powf.c b/lib/libm/src/w_powf.c deleted file mode 100644 index 6d4772a3830..00000000000 --- a/lib/libm/src/w_powf.c +++ /dev/null @@ -1,67 +0,0 @@ -/* w_powf.c -- float version of w_pow.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_powf.c,v 1.3 1995/05/10 20:49:41 jtc Exp $"; -#endif - -/* - * wrapper powf(x,y) return x**y - */ - -#include "math.h" -#include "math_private.h" - -float -powf(float x, float y) /* wrapper powf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_powf(x,y); -#else - float z; - z=__ieee754_powf(x,y); - if(_LIB_VERSION == _IEEE_|| isnanf(y)) return z; - if(isnanf(x)) { - if(y==(float)0.0) - /* powf(NaN,0.0) */ - return (float)__kernel_standard((double)x,(double)y,142); - else - return z; - } - if(x==(float)0.0){ - if(y==(float)0.0) - /* powf(0.0,0.0) */ - return (float)__kernel_standard((double)x,(double)y,120); - if(finitef(y)&&y<(float)0.0) - /* powf(0.0,negative) */ - return (float)__kernel_standard((double)x,(double)y,123); - return z; - } - if(!finitef(z)) { - if(finitef(x)&&finitef(y)) { - if(isnanf(z)) - /* powf neg**non-int */ - return (float)__kernel_standard((double)x,(double)y,124); - else - /* powf overflow */ - return (float)__kernel_standard((double)x,(double)y,121); - } - } - if(z==(float)0.0&&finitef(x)&&finitef(y)) - /* powf underflow */ - return (float)__kernel_standard((double)x,(double)y,122); - return z; -#endif -} diff --git a/lib/libm/src/w_remainder.c b/lib/libm/src/w_remainder.c deleted file mode 100644 index 50a41e77c4b..00000000000 --- a/lib/libm/src/w_remainder.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_remainder.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_remainder.c,v 1.6 1995/05/10 20:49:44 jtc Exp $"; -#endif - -/* - * wrapper remainder(x,p) - */ - -#include "math.h" -#include "math_private.h" - -double -remainder(double x, double y) /* wrapper remainder */ -{ -#ifdef _IEEE_LIBM - return __ieee754_remainder(x,y); -#else - double z; - z = __ieee754_remainder(x,y); - if(_LIB_VERSION == _IEEE_ || isnan(y)) return z; - if(y==0.0) - return __kernel_standard(x,y,28); /* remainder(x,0) */ - else - return z; -#endif -} diff --git a/lib/libm/src/w_remainderf.c b/lib/libm/src/w_remainderf.c deleted file mode 100644 index 0339c546a94..00000000000 --- a/lib/libm/src/w_remainderf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_remainderf.c -- float version of w_remainder.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_remainderf.c,v 1.3 1995/05/10 20:49:46 jtc Exp $"; -#endif - -/* - * wrapper remainderf(x,p) - */ - -#include "math.h" -#include "math_private.h" - -float -remainderf(float x, float y) /* wrapper remainder */ -{ -#ifdef _IEEE_LIBM - return __ieee754_remainderf(x,y); -#else - float z; - z = __ieee754_remainderf(x,y); - if(_LIB_VERSION == _IEEE_ || isnanf(y)) return z; - if(y==(float)0.0) - /* remainder(x,0) */ - return (float)__kernel_standard((double)x,(double)y,128); - else - return z; -#endif -} diff --git a/lib/libm/src/w_scalb.c b/lib/libm/src/w_scalb.c deleted file mode 100644 index d956ab75ee8..00000000000 --- a/lib/libm/src/w_scalb.c +++ /dev/null @@ -1,52 +0,0 @@ -/* @(#)w_scalb.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_scalb.c,v 1.6 1995/05/10 20:49:48 jtc Exp $"; -#endif - -/* - * wrapper scalb(double x, double fn) is provide for - * passing various standard test suite. One - * should use scalbn() instead. - */ - -#include "math.h" -#include "math_private.h" - -#include <errno.h> - -double -#ifdef _SCALB_INT -scalb(double x, int fn) /* wrapper scalb */ -#else -scalb(double x, double fn) /* wrapper scalb */ -#endif -{ -#ifdef _IEEE_LIBM - return __ieee754_scalb(x,fn); -#else - double z; - z = __ieee754_scalb(x,fn); - if(_LIB_VERSION == _IEEE_) return z; - if(!(finite(z)||isnan(z))&&finite(x)) { - return __kernel_standard(x,(double)fn,32); /* scalb overflow */ - } - if(z==0.0&&z!=x) { - return __kernel_standard(x,(double)fn,33); /* scalb underflow */ - } -#ifndef _SCALB_INT - if(!finite(fn)) errno = ERANGE; -#endif - return z; -#endif -} diff --git a/lib/libm/src/w_scalbf.c b/lib/libm/src/w_scalbf.c deleted file mode 100644 index 9542611f1b6..00000000000 --- a/lib/libm/src/w_scalbf.c +++ /dev/null @@ -1,57 +0,0 @@ -/* w_scalbf.c -- float version of w_scalb.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_scalbf.c,v 1.3 1995/05/10 20:49:50 jtc Exp $"; -#endif - -/* - * wrapper scalbf(float x, float fn) is provide for - * passing various standard test suite. One - * should use scalbn() instead. - */ - -#include "math.h" -#include "math_private.h" - -#include <errno.h> - -float -#ifdef _SCALB_INT -scalbf(float x, int fn) /* wrapper scalbf */ -#else -scalbf(float x, float fn) /* wrapper scalbf */ -#endif -{ -#ifdef _IEEE_LIBM - return __ieee754_scalbf(x,fn); -#else - float z; - z = __ieee754_scalbf(x,fn); - if(_LIB_VERSION == _IEEE_) return z; - if(!(finitef(z)||isnanf(z))&&finitef(x)) { - /* scalbf overflow */ - return (float)__kernel_standard((double)x,(double)fn,132); - } - if(z==(float)0.0&&z!=x) { - /* scalbf underflow */ - return (float)__kernel_standard((double)x,(double)fn,133); - } -#ifndef _SCALB_INT - if(!finitef(fn)) errno = ERANGE; -#endif - return z; -#endif -} diff --git a/lib/libm/src/w_sinh.c b/lib/libm/src/w_sinh.c deleted file mode 100644 index c02a0ae0531..00000000000 --- a/lib/libm/src/w_sinh.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_sinh.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_sinh.c,v 1.6 1995/05/10 20:49:51 jtc Exp $"; -#endif - -/* - * wrapper sinh(x) - */ - -#include "math.h" -#include "math_private.h" - -double -sinh(double x) /* wrapper sinh */ -{ -#ifdef _IEEE_LIBM - return __ieee754_sinh(x); -#else - double z; - z = __ieee754_sinh(x); - if(_LIB_VERSION == _IEEE_) return z; - if(!finite(z)&&finite(x)) { - return __kernel_standard(x,x,25); /* sinh overflow */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_sinhf.c b/lib/libm/src/w_sinhf.c deleted file mode 100644 index 58df8cd515a..00000000000 --- a/lib/libm/src/w_sinhf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_sinhf.c -- float version of w_sinh.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_sinhf.c,v 1.3 1995/05/10 20:49:54 jtc Exp $"; -#endif - -/* - * wrapper sinhf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -sinhf(float x) /* wrapper sinhf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_sinhf(x); -#else - float z; - z = __ieee754_sinhf(x); - if(_LIB_VERSION == _IEEE_) return z; - if(!finitef(z)&&finitef(x)) { - /* sinhf overflow */ - return (float)__kernel_standard((double)x,(double)x,125); - } else - return z; -#endif -} diff --git a/lib/libm/src/w_sqrt.c b/lib/libm/src/w_sqrt.c deleted file mode 100644 index fec804b282c..00000000000 --- a/lib/libm/src/w_sqrt.c +++ /dev/null @@ -1,38 +0,0 @@ -/* @(#)w_sqrt.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_sqrt.c,v 1.6 1995/05/10 20:49:55 jtc Exp $"; -#endif - -/* - * wrapper sqrt(x) - */ - -#include "math.h" -#include "math_private.h" - -double -sqrt(double x) /* wrapper sqrt */ -{ -#ifdef _IEEE_LIBM - return __ieee754_sqrt(x); -#else - double z; - z = __ieee754_sqrt(x); - if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; - if(x<0.0) { - return __kernel_standard(x,x,26); /* sqrt(negative) */ - } else - return z; -#endif -} diff --git a/lib/libm/src/w_sqrtf.c b/lib/libm/src/w_sqrtf.c deleted file mode 100644 index fb21a63529c..00000000000 --- a/lib/libm/src/w_sqrtf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* w_sqrtf.c -- float version of w_sqrt.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#if defined(LIBM_SCCS) && !defined(lint) -static char rcsid[] = "$NetBSD: w_sqrtf.c,v 1.3 1995/05/10 20:49:59 jtc Exp $"; -#endif - -/* - * wrapper sqrtf(x) - */ - -#include "math.h" -#include "math_private.h" - -float -sqrtf(float x) /* wrapper sqrtf */ -{ -#ifdef _IEEE_LIBM - return __ieee754_sqrtf(x); -#else - float z; - z = __ieee754_sqrtf(x); - if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; - if(x<(float)0.0) { - /* sqrtf(negative) */ - return (float)__kernel_standard((double)x,(double)x,126); - } else - return z; -#endif -} diff --git a/regress/lib/libc/Makefile b/regress/lib/libc/Makefile index 689f87aa03b..dc9beab1e15 100644 --- a/regress/lib/libc/Makefile +++ b/regress/lib/libc/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.26 2007/09/03 14:42:43 millert Exp $ +# $OpenBSD: Makefile,v 1.27 2008/09/07 20:36:10 martynas Exp $ -SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname getaddrinfo -SUBDIR+= getcap getopt_long hsearch longjmp locale malloc -SUBDIR+= netdb popen regex setjmp setjmp-signal sigreturn sigsetjmp +SUBDIR+= _setjmp alloca atexit basename cxa-atexit db dirname fpclassify +SUBDIR+= getaddrinfo getcap getopt_long hsearch longjmp locale malloc +SUBDIR+= netdb popen printf regex setjmp setjmp-signal sigreturn sigsetjmp SUBDIR+= sprintf strerror strtod strtonum telldir time vis .if (${MACHINE_ARCH} != "vax") diff --git a/regress/lib/libc/fpclassify/Makefile b/regress/lib/libc/fpclassify/Makefile new file mode 100644 index 00000000000..96916d20e70 --- /dev/null +++ b/regress/lib/libc/fpclassify/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2008/09/07 20:36:10 martynas Exp $ + +PROG= fpclassify + +.include <bsd.regress.mk> diff --git a/regress/lib/libc/fpclassify/fpclassify.c b/regress/lib/libc/fpclassify/fpclassify.c new file mode 100644 index 00000000000..174c04d983f --- /dev/null +++ b/regress/lib/libc/fpclassify/fpclassify.c @@ -0,0 +1,76 @@ +/* $OpenBSD: fpclassify.c,v 1.1 2008/09/07 20:36:10 martynas Exp $ */ +/*- + * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: src/tools/regression/lib/libc/gen/test-fpclassify.c,v 1.3 2003/03/27 05:32:28 das Exp $ + */ + +#include <assert.h> +#include <float.h> +#include <math.h> +#include <stdlib.h> + +int +main(void) +{ + + assert(fpclassify((float)0) == FP_ZERO); + assert(fpclassify((float)-0.0) == FP_ZERO); + assert(fpclassify((float)1) == FP_NORMAL); + assert(fpclassify((float)1000) == FP_NORMAL); +#ifndef __alpha__ + assert(fpclassify(0x1.2p-150f) == FP_SUBNORMAL); +#endif /* !__alpha__ */ + assert(fpclassify(HUGE_VALF) == FP_INFINITE); + assert(fpclassify((float)HUGE_VAL) == FP_INFINITE); + assert(fpclassify((float)HUGE_VALL) == FP_INFINITE); + assert(fpclassify(NAN) == FP_NAN); + + assert(fpclassify((double)0) == FP_ZERO); + assert(fpclassify((double)-0) == FP_ZERO); + assert(fpclassify((double)1) == FP_NORMAL); + assert(fpclassify((double)1000) == FP_NORMAL); +#ifndef __alpha__ + assert(fpclassify(0x1.2p-1075) == FP_SUBNORMAL); +#endif /* !__alpha__ */ + assert(fpclassify(HUGE_VAL) == FP_INFINITE); + assert(fpclassify((double)HUGE_VALF) == FP_INFINITE); + assert(fpclassify((double)HUGE_VALL) == FP_INFINITE); + assert(fpclassify((double)NAN) == FP_NAN); + + assert(fpclassify((long double)0) == FP_ZERO); + assert(fpclassify((long double)-0.0) == FP_ZERO); + assert(fpclassify((long double)1) == FP_NORMAL); + assert(fpclassify((long double)1000) == FP_NORMAL); +#if (LDBL_MANT_DIG > DBL_MANT_DIG) + assert(fpclassify(0x1.2p-16383L) == FP_SUBNORMAL); +#endif /* (LDBL_MANT_DIG > DBL_MANT_DIG) */ + assert(fpclassify(HUGE_VALL) == FP_INFINITE); + assert(fpclassify((long double)HUGE_VALF) == FP_INFINITE); + assert(fpclassify((long double)HUGE_VAL) == FP_INFINITE); + assert(fpclassify((long double)NAN) == FP_NAN); + + return (0); +} diff --git a/regress/lib/libc/printf/Makefile b/regress/lib/libc/printf/Makefile new file mode 100644 index 00000000000..c2e2732d6e1 --- /dev/null +++ b/regress/lib/libc/printf/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2008/09/07 20:36:10 martynas Exp $ + +PROG= fp + +.include <bsd.regress.mk> diff --git a/regress/lib/libc/printf/fp.c b/regress/lib/libc/printf/fp.c new file mode 100644 index 00000000000..6ed52fdb494 --- /dev/null +++ b/regress/lib/libc/printf/fp.c @@ -0,0 +1,217 @@ +/* $OpenBSD: fp.c,v 1.1 2008/09/07 20:36:10 martynas Exp $ */ +/*- + * Copyright (c) 2002, 2005 David Schultz <das@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Test for printf() floating point formats. + */ + +#include <assert.h> +#include <err.h> +#include <float.h> +#include <math.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#define testfmt(result, fmt, ...) \ + _testfmt((result), __LINE__, #__VA_ARGS__, fmt, __VA_ARGS__) +void _testfmt(const char *, int, const char *, const char *, ...); +void smash_stack(void); + +int +main(int argc, char *argv[]) +{ + /* + * Basic tests of decimal output functionality. + */ + testfmt(" 1.000000E+00", "%13E", 1.0); + testfmt(" 1.000000", "%13f", 1.0); + testfmt(" 1", "%13G", 1.0); + testfmt(" 1.000000E+00", "%13LE", 1.0L); + testfmt(" 1.000000", "%13Lf", 1.0L); + testfmt(" 1", "%13LG", 1.0L); + + testfmt("2.718282", "%.*f", -2, 2.7182818); + + testfmt("1.234568e+06", "%e", 1234567.8); + testfmt("1234567.800000", "%f", 1234567.8); + testfmt("1.23457E+06", "%G", 1234567.8); + testfmt("1.234568e+06", "%Le", 1234567.8L); + testfmt("1234567.800000", "%Lf", 1234567.8L); + testfmt("1.23457E+06", "%LG", 1234567.8L); + +#if (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) + testfmt("123456789.864210", "%Lf", 123456789.8642097531L); + testfmt("-1.23457E+08", "%LG", -123456789.8642097531L); + testfmt("123456789.8642097531", "%.10Lf", 123456789.8642097531L); + testfmt(" 3.141592653589793238e-4000", "%L27.18Le", + 3.14159265358979323846e-4000L); +#endif /* (LDBL_MANT_DIG > DBL_MANT_DIG) && !defined(__i386__) */ + + /* + * Infinities and NaNs + */ +#ifdef NAN + testfmt("nan", "%e", NAN); + testfmt("NAN", "%F", NAN); + testfmt("nan", "%g", NAN); + testfmt("NAN", "%LE", (long double)NAN); + testfmt(" nan", "%05e", NAN); +#endif /* NAN */ + + testfmt("INF", "%E", HUGE_VAL); + testfmt("-inf", "%f", -HUGE_VAL); + testfmt("+inf", "%+g", HUGE_VAL); + testfmt(" inf", "%4.2Le", HUGE_VALL); + testfmt("-inf", "%Lf", -HUGE_VALL); + testfmt(" inf", "%05e", HUGE_VAL); + testfmt(" -inf", "%05e", -HUGE_VAL); + + /* + * Padding + */ + testfmt("0.000000e+00", "%e", 0.0); + testfmt("0.000000", "%F", (double)0.0); + testfmt("0", "%G", 0.0); + testfmt(" 0", "%3.0Lg", 0.0L); + testfmt(" 0", "%5.0f", 0.001); + + /* + * Precision specifiers + */ + testfmt("1.0123e+00", "%.4e", 1.0123456789); + testfmt("1.0123", "%.4f", 1.0123456789); + testfmt("1.012", "%.4g", 1.0123456789); + testfmt("1.2346e-02", "%.4e", 0.0123456789); + testfmt("0.0123", "%.4f", 0.0123456789); + testfmt("0.01235", "%.4g", 0.0123456789); + + /* + * Signed conversions + */ + testfmt("+2.500000e-01", "%+e", 0.25); + testfmt("+0.000000", "%+F", 0.0); + testfmt("-1", "%+g", -1.0); + + testfmt("-1.000000e+00", "% e", -1.0); + testfmt("+1.000000", "% +f", 1.0); + testfmt(" 1", "% g", 1.0); + testfmt(" 0", "% g", 0.0); + + /* + * ``Alternate form'' + */ + testfmt("1.250e+00", "%#.3e", 1.25); + testfmt("123.000000", "%#f", 123.0); + testfmt(" 12345.", "%#7.5g", 12345.0); + testfmt(" 1.00000", "%#8g", 1.0); + testfmt("0.0", "%#.2g", 0.0); + + /* + * Padding and decimal point placement + */ + testfmt("03.2E+00", "%08.1E", 3.25); + testfmt("003.25", "%06.2F", 3.25); + testfmt("0003.25", "%07.4G", 3.25); + + testfmt("3.14159e-05", "%g", 3.14159e-5); + testfmt("0.000314159", "%g", 3.14159e-4); + testfmt("3.14159e+06", "%g", 3.14159e6); + testfmt("314159", "%g", 3.14159e5); + testfmt("314159.", "%#g", 3.14159e5); + + testfmt(" 9.000000e+03", "%13e", 9000.0); + testfmt(" 9000.000000", "%12f", 9000.0); + testfmt(" 9000", "%5g", 9000.0); + testfmt(" 900000.", "%#8g", 900000.0); + testfmt(" 9e+06", "%6g", 9000000.0); + testfmt(" 9.000000e-04", "%13e", 0.0009); + testfmt(" 0.000900", "%9f", 0.0009); + testfmt(" 0.0009", "%7g", 0.0009); + testfmt(" 9e-05", "%6g", 0.00009); + testfmt(" 9.00000e-05", "%#12g", 0.00009); + testfmt(" 9.e-05", "%#7.1g", 0.00009); + + testfmt(" 0.0", "%4.1f", 0.0); + testfmt("90.0", "%4.1f", 90.0); + testfmt(" 100", "%4.0f", 100.0); + testfmt("9.0e+01", "%4.1e", 90.0); + testfmt("1e+02", "%4.0e", 100.0); + + /* + * Hexadecimal floating point (%a, %A) tests. Some of these + * are only valid if the implementation converts to hex digits + * on nibble boundaries. + */ + testfmt("0x0p+0", "%a", 0x0.0p0); + testfmt("0X0.P+0", "%#LA", 0x0.0p0L); +#ifdef NAN + testfmt("inf", "%La", (long double)INFINITY); + testfmt("+INF", "%+A", INFINITY); + testfmt("nan", "%La", (long double)NAN); + testfmt("NAN", "%A", NAN); +#endif /* NAN */ + + testfmt(" 0x1.23p+0", "%10a", 0x1.23p0); + testfmt(" 0x1.23p-500", "%12a", 0x1.23p-500); + testfmt(" 0x1.2p+40", "%10.1a", 0x1.23p40); + testfmt(" 0X1.230000000000000000000000P-4", "%32.24A", 0x1.23p-4); + testfmt("0x1p-1074", "%a", 0x1p-1074); + testfmt("0x1.2345p-1024", "%a", 0x1.2345p-1024); + + return (0); +} + +void +smash_stack(void) +{ + static uint32_t junk = 0xdeadbeef; + uint32_t buf[512]; + int i; + + for (i = 0; i < sizeof(buf) / sizeof(buf[0]); i++) + buf[i] = junk; +} + +void +_testfmt(const char *result, int line, const char *argstr, const char *fmt,...) +{ + char s[100]; + va_list ap; + + va_start(ap, fmt); + smash_stack(); + vsnprintf(s, sizeof(s), fmt, ap); + if (strcmp(result, s) != 0) { + fprintf(stderr, + "%d: printf(\"%s\", %s) ==> [%s], expected [%s]\n", + line, fmt, argstr, s, result); + abort(); + } +} diff --git a/regress/lib/libm/tgamma/tgamma.c b/regress/lib/libm/tgamma/tgamma.c index a3b1b6964a6..491fe6efcbb 100644 --- a/regress/lib/libm/tgamma/tgamma.c +++ b/regress/lib/libm/tgamma/tgamma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tgamma.c,v 1.1 2008/06/11 15:07:34 martynas Exp $ */ +/* $OpenBSD: tgamma.c,v 1.2 2008/09/07 20:36:10 martynas Exp $ */ /* Written by Martynas Venckus, 2008, Public domain. */ @@ -83,8 +83,12 @@ main(void) if (!_isinf(x)) errx(1, "tgamma(171.64) = %f", x); - x = tgamma(0); - if (!_isinf(x)) + x = tgamma(0.0); + if (!_isinf(x) || x < 0) + errx(1, "tgamma(0) = %f", x); + + x = tgamma(-0.0); + if (!_isinf(x) || x > 0) errx(1, "tgamma(0) = %f", x); x = tgamma(-HUGE_VAL); @@ -95,8 +99,8 @@ main(void) if (!_isinf(x)) errx(1, "tgamma(HUGE_VAL) = %f", x); -#if _IEEE /* VAX doesn't have NaN */ - x = tgamma(0.0/0.0); +#ifdef NAN + x = tgamma(NAN); if (!_isnan(x)) errx(1, "tgamma(NaN) = %f", x); #endif diff --git a/sys/arch/alpha/include/ieee.h b/sys/arch/alpha/include/ieee.h index e5ed1da001d..0fbbe82482f 100644 --- a/sys/arch/alpha/include/ieee.h +++ b/sys/arch/alpha/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.4 2003/06/02 23:27:43 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.5 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.1 1995/02/13 23:07:40 cgd Exp $ */ /* @@ -81,6 +81,8 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 struct ieee_single { diff --git a/sys/arch/amd64/include/ieee.h b/sys/arch/amd64/include/ieee.h index 5a34355d223..74856b20ebf 100644 --- a/sys/arch/amd64/include/ieee.h +++ b/sys/arch/amd64/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.1 2004/01/28 01:39:39 mickey Exp $ */ +/* $OpenBSD: ieee.h,v 1.2 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */ /* @@ -79,10 +79,19 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #define EXT_EXPBITS 15 -#define EXT_FRACBITS 112 +#define EXT_FRACHBITS 32 +#define EXT_FRACLBITS 32 +#define EXT_FRACBITS 64 + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_frach; \ +} while(0) struct ieee_single { u_int sng_frac:23; @@ -99,11 +108,11 @@ struct ieee_double { struct ieee_ext { u_int ext_fracl; - u_int ext_fraclm; - u_int ext_frachm; - u_int ext_frach:16; + u_int ext_frach; u_int ext_exp:15; u_int ext_sign:1; + u_int ext_padl:16; + u_int ext_padh; }; /* diff --git a/sys/arch/arm/include/ieee.h b/sys/arch/arm/include/ieee.h index fb3620bde41..c0ef9ca2fbd 100644 --- a/sys/arch/arm/include/ieee.h +++ b/sys/arch/arm/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2008/07/24 17:36:52 deraadt Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $ */ /* @@ -92,13 +92,21 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #ifndef __VFP_FP__ #define E80_EXPBITS 15 +#define E80_FRACHBITS 31 +#define E80_FRACLBITS 32 #define E80_FRACBITS 64 #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 16 +#define EXT_FRACHMBITS 32 +#define EXT_FRACLMBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 112 #endif diff --git a/sys/arch/hppa/include/ieee.h b/sys/arch/hppa/include/ieee.h index d908f10c698..d9d263abe37 100644 --- a/sys/arch/hppa/include/ieee.h +++ b/sys/arch/hppa/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:46 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,6 +78,8 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #ifdef notyet @@ -85,9 +87,6 @@ #define E80_FRACBITS 64 #endif -#define EXT_EXPBITS 15 -#define EXT_FRACBITS 112 - struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; @@ -101,15 +100,6 @@ struct ieee_double { u_int dbl_fracl; }; -struct ieee_ext { - u_int ext_sign:1; - u_int ext_exp:15; - u_int ext_frach:16; - u_int ext_frachm; - u_int ext_fraclm; - u_int ext_fracl; -}; - /* * Floats whose exponent is in [1..INFNAN) (of whatever type) are * `normal'. Floats whose exponent is INFNAN are either Inf or NaN. @@ -121,12 +111,10 @@ struct ieee_ext { */ #define SNG_EXP_INFNAN 255 #define DBL_EXP_INFNAN 2047 -#define EXT_EXP_INFNAN 32767 #if 0 #define SNG_QUIETNAN (1 << 22) #define DBL_QUIETNAN (1 << 19) -#define EXT_QUIETNAN (1 << 15) #endif /* @@ -134,4 +122,3 @@ struct ieee_ext { */ #define SNG_EXP_BIAS 127 #define DBL_EXP_BIAS 1023 -#define EXT_EXP_BIAS 16383 diff --git a/sys/arch/hppa64/include/ieee.h b/sys/arch/hppa64/include/ieee.h index dfd8044fd80..f61c962b11a 100644 --- a/sys/arch/hppa64/include/ieee.h +++ b/sys/arch/hppa64/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.1 2005/04/01 10:40:48 mickey Exp $ */ +/* $OpenBSD: ieee.h,v 1.2 2008/09/07 20:36:06 martynas Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,6 +78,8 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #ifdef notyet @@ -86,8 +88,21 @@ #endif #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 16 +#define EXT_FRACHMBITS 32 +#define EXT_FRACLMBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 112 +#define EXT_IMPLICIT_NBIT + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_fraclm; \ + (a)[2] = (uint32_t)(p)->ext_frachm; \ + (a)[3] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; diff --git a/sys/arch/i386/include/ieee.h b/sys/arch/i386/include/ieee.h index 55b3703277c..865fcb9eec6 100644 --- a/sys/arch/i386/include/ieee.h +++ b/sys/arch/i386/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:47 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.1 1996/09/30 16:34:25 ws Exp $ */ /* @@ -79,10 +79,19 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #define EXT_EXPBITS 15 -#define EXT_FRACBITS 112 +#define EXT_FRACHBITS 32 +#define EXT_FRACLBITS 32 +#define EXT_FRACBITS 64 + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_frach; \ +} while(0) struct ieee_single { u_int sng_frac:23; @@ -99,11 +108,10 @@ struct ieee_double { struct ieee_ext { u_int ext_fracl; - u_int ext_fraclm; - u_int ext_frachm; - u_int ext_frach:16; + u_int ext_frach; u_int ext_exp:15; u_int ext_sign:1; + u_int ext_pad:16; }; /* diff --git a/sys/arch/m68k/include/float.h b/sys/arch/m68k/include/float.h index cf252b96b1b..954e5733512 100644 --- a/sys/arch/m68k/include/float.h +++ b/sys/arch/m68k/include/float.h @@ -1,4 +1,4 @@ -/* $OpenBSD: float.h,v 1.6 2008/07/21 20:50:54 martynas Exp $ */ +/* $OpenBSD: float.h,v 1.7 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: float.h,v 1.10 1995/06/20 20:45:41 jtc Exp $ */ /* @@ -48,9 +48,9 @@ __END_DECLS #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ #define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */ -#define FLT_MIN_EXP -125 /* emin */ +#define FLT_MIN_EXP (-125) /* emin */ #define FLT_MIN 1.17549435E-38F /* b**(emin-1) */ -#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */ +#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */ #define FLT_MAX_EXP 128 /* emax */ #define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */ #define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */ @@ -58,21 +58,21 @@ __END_DECLS #define DBL_MANT_DIG 53 #define DBL_EPSILON 2.2204460492503131E-16 #define DBL_DIG 15 -#define DBL_MIN_EXP -1021 +#define DBL_MIN_EXP (-1021) #define DBL_MIN 2.2250738585072014E-308 -#define DBL_MIN_10_EXP -307 +#define DBL_MIN_10_EXP (-307) #define DBL_MAX_EXP 1024 #define DBL_MAX 1.7976931348623157E+308 #define DBL_MAX_10_EXP 308 -#define LDBL_MANT_DIG DBL_MANT_DIG -#define LDBL_EPSILON DBL_EPSILON -#define LDBL_DIG DBL_DIG -#define LDBL_MIN_EXP DBL_MIN_EXP -#define LDBL_MIN DBL_MIN -#define LDBL_MIN_10_EXP DBL_MIN_10_EXP -#define LDBL_MAX_EXP DBL_MAX_EXP -#define LDBL_MAX DBL_MAX -#define LDBL_MAX_10_EXP DBL_MAX_10_EXP +#define LDBL_MANT_DIG 64 +#define LDBL_EPSILON 1.08420217248550443401e-19L +#define LDBL_DIG 18 +#define LDBL_MIN_EXP (-16381) +#define LDBL_MIN 3.36210314311209350626e-4932L +#define LDBL_MIN_10_EXP (-4931) +#define LDBL_MAX_EXP 16384 +#define LDBL_MAX 1.18973149535723176502e+4932L +#define LDBL_MAX_10_EXP 4932 #endif /* !_M68K_FLOAT_H_ */ diff --git a/sys/arch/m68k/include/ieee.h b/sys/arch/m68k/include/ieee.h index 05f903c2286..3ed9aad9885 100644 --- a/sys/arch/m68k/include/ieee.h +++ b/sys/arch/m68k/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.3 2006/01/16 22:05:59 miod Exp $ */ +/* $OpenBSD: ieee.h,v 1.4 2008/09/07 20:36:06 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.2 1994/11/20 20:53:10 deraadt Exp $ */ /* @@ -79,11 +79,20 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 64 +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; @@ -101,8 +110,7 @@ struct ieee_ext { u_int ext_sign:1; u_int ext_exp:15; u_int ext_zero:16; - u_int ext_int:1; - u_int ext_frach:31; + u_int ext_frach; u_int ext_fracl; }; diff --git a/sys/arch/m88k/include/float.h b/sys/arch/m88k/include/float.h index e6c0d7f3240..8e46928dafb 100644 --- a/sys/arch/m88k/include/float.h +++ b/sys/arch/m88k/include/float.h @@ -1,4 +1,4 @@ -/* $OpenBSD: float.h,v 1.2 2008/07/21 20:50:54 martynas Exp $ */ +/* $OpenBSD: float.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */ /* * Copyright (c) 1989 Regents of the University of California. @@ -47,9 +47,9 @@ __END_DECLS #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ #define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */ -#define FLT_MIN_EXP -125 /* emin */ +#define FLT_MIN_EXP (-125) /* emin */ #define FLT_MIN 1.17549435E-38F /* b**(emin-1) */ -#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */ +#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */ #define FLT_MAX_EXP 128 /* emax */ #define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */ #define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */ @@ -57,21 +57,21 @@ __END_DECLS #define DBL_MANT_DIG 53 #define DBL_EPSILON 2.2204460492503131E-16 #define DBL_DIG 15 -#define DBL_MIN_EXP -1021 +#define DBL_MIN_EXP (-1021) #define DBL_MIN 2.2250738585072014E-308 -#define DBL_MIN_10_EXP -307 +#define DBL_MIN_10_EXP (-307) #define DBL_MAX_EXP 1024 #define DBL_MAX 1.7976931348623157E+308 #define DBL_MAX_10_EXP 308 -#define LDBL_MANT_DIG DBL_MANT_DIG -#define LDBL_EPSILON DBL_EPSILON -#define LDBL_DIG DBL_DIG -#define LDBL_MIN_EXP DBL_MIN_EXP -#define LDBL_MIN DBL_MIN -#define LDBL_MIN_10_EXP DBL_MIN_10_EXP -#define LDBL_MAX_EXP DBL_MAX_EXP -#define LDBL_MAX DBL_MAX -#define LDBL_MAX_10_EXP DBL_MAX_10_EXP +#define LDBL_MANT_DIG 64 +#define LDBL_EPSILON 1.08420217248550443401e-19L +#define LDBL_DIG 18 +#define LDBL_MIN_EXP (-16381) +#define LDBL_MIN 3.36210314311209350626e-4932L +#define LDBL_MIN_10_EXP (-4931) +#define LDBL_MAX_EXP 16384 +#define LDBL_MAX 1.18973149535723176502e+4932L +#define LDBL_MAX_10_EXP 4932 #endif /* __M88K_FLOAT_H__ */ diff --git a/sys/arch/m88k/include/ieee.h b/sys/arch/m88k/include/ieee.h index a849c33906e..d68677c46aa 100644 --- a/sys/arch/m88k/include/ieee.h +++ b/sys/arch/m88k/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2006/05/04 19:28:43 miod Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:06 martynas Exp $ */ /* * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -77,11 +77,20 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 64 +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; @@ -98,8 +107,7 @@ struct ieee_double { struct ieee_ext { u_int ext_sign:1; u_int ext_exp:15; - u_int ext_lead:1; - u_int ext_frach:31; + u_int ext_frach; u_int ext_fracl; }; diff --git a/sys/arch/mips64/include/float.h b/sys/arch/mips64/include/float.h index f3fe1b0ed1e..dcb397c28e9 100644 --- a/sys/arch/mips64/include/float.h +++ b/sys/arch/mips64/include/float.h @@ -1,4 +1,4 @@ -/* $OpenBSD: float.h,v 1.4 2008/07/21 20:50:54 martynas Exp $ */ +/* $OpenBSD: float.h,v 1.5 2008/09/07 20:36:06 martynas Exp $ */ /* * Copyright (c) 1989, 1993 @@ -47,9 +47,9 @@ __END_DECLS #define FLT_MANT_DIG 24 /* p */ #define FLT_EPSILON 1.19209290E-07F /* b**(1-p) */ #define FLT_DIG 6 /* floor((p-1)*log10(b))+(b == 10) */ -#define FLT_MIN_EXP -125 /* emin */ +#define FLT_MIN_EXP (-125) /* emin */ #define FLT_MIN 1.17549435E-38F /* b**(emin-1) */ -#define FLT_MIN_10_EXP -37 /* ceil(log10(b**(emin-1))) */ +#define FLT_MIN_10_EXP (-37) /* ceil(log10(b**(emin-1))) */ #define FLT_MAX_EXP 128 /* emax */ #define FLT_MAX 3.40282347E+38F /* (1-b**(-p))*b**emax */ #define FLT_MAX_10_EXP 38 /* floor(log10((1-b**(-p))*b**emax)) */ @@ -57,21 +57,21 @@ __END_DECLS #define DBL_MANT_DIG 53 #define DBL_EPSILON 2.2204460492503131E-16 #define DBL_DIG 15 -#define DBL_MIN_EXP -1021 +#define DBL_MIN_EXP (-1021) #define DBL_MIN 2.225073858507201E-308 -#define DBL_MIN_10_EXP -307 +#define DBL_MIN_10_EXP (-307) #define DBL_MAX_EXP 1024 #define DBL_MAX 1.797693134862316E+308 #define DBL_MAX_10_EXP 308 -#define LDBL_MANT_DIG DBL_MANT_DIG -#define LDBL_EPSILON DBL_EPSILON -#define LDBL_DIG DBL_DIG -#define LDBL_MIN_EXP DBL_MIN_EXP -#define LDBL_MIN DBL_MIN -#define LDBL_MIN_10_EXP DBL_MIN_10_EXP -#define LDBL_MAX_EXP DBL_MAX_EXP -#define LDBL_MAX DBL_MAX -#define LDBL_MAX_10_EXP DBL_MAX_10_EXP +#define LDBL_MANT_DIG 113 +#define LDBL_EPSILON 1.92592994438723585305597794258492732e-34L +#define LDBL_DIG 33 +#define LDBL_MIN_EXP (-16381) +#define LDBL_MIN 3.36210314311209350626267781732175260e-4932L +#define LDBL_MIN_10_EXP (-4931) +#define LDBL_MAX_EXP 16384 +#define LDBL_MAX 1.18973149535723176508575932662800702e+4932L +#define LDBL_MAX_10_EXP 4932 #endif /* !_MIPS_FLOAT_H_ */ diff --git a/sys/arch/mips64/include/ieee.h b/sys/arch/mips64/include/ieee.h index 28b7d8b21d0..a683ec5bc45 100644 --- a/sys/arch/mips64/include/ieee.h +++ b/sys/arch/mips64/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2005/08/07 07:29:44 miod Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,11 +78,26 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 16 +#define EXT_FRACHMBITS 32 +#define EXT_FRACLMBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 112 +#define EXT_IMPLICIT_NBIT + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_fraclm; \ + (a)[2] = (uint32_t)(p)->ext_frachm; \ + (a)[3] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; diff --git a/sys/arch/powerpc/include/ieee.h b/sys/arch/powerpc/include/ieee.h index ffa6bf97811..de0b4f76b05 100644 --- a/sys/arch/powerpc/include/ieee.h +++ b/sys/arch/powerpc/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.4 2003/06/02 23:27:53 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.5 2008/09/07 20:36:07 martynas Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,11 +78,10 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 -#define EXT_EXPBITS 15 -#define EXT_FRACBITS 112 - struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; @@ -96,15 +95,6 @@ struct ieee_double { u_int dbl_fracl; }; -struct ieee_ext { - u_int ext_sign:1; - u_int ext_exp:15; - u_int ext_frach:16; - u_int ext_frachm; - u_int ext_fraclm; - u_int ext_fracl; -}; - /* * Floats whose exponent is in [1..INFNAN) (of whatever type) are * `normal'. Floats whose exponent is INFNAN are either Inf or NaN. @@ -116,12 +106,10 @@ struct ieee_ext { */ #define SNG_EXP_INFNAN 255 #define DBL_EXP_INFNAN 2047 -#define EXT_EXP_INFNAN 32767 #if 0 #define SNG_QUIETNAN (1 << 22) #define DBL_QUIETNAN (1 << 19) -#define EXT_QUIETNAN (1 << 15) #endif /* @@ -129,4 +117,3 @@ struct ieee_ext { */ #define SNG_EXP_BIAS 127 #define DBL_EXP_BIAS 1023 -#define EXT_EXP_BIAS 16383 diff --git a/sys/arch/sh/include/ieee.h b/sys/arch/sh/include/ieee.h index 7646f85edfc..5de8eec3cf8 100644 --- a/sys/arch/sh/include/ieee.h +++ b/sys/arch/sh/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2006/11/10 20:29:36 otto Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */ /* * Copyright (c) 1992, 1993 @@ -78,11 +78,10 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 -#define EXT_EXPBITS 15 -#define EXT_FRACBITS 112 - struct ieee_single { u_int sng_frac:23; u_int sng_exp:8; @@ -96,15 +95,6 @@ struct ieee_double { u_int dbl_sign:1; }; -struct ieee_ext { - u_int ext_sign:1; - u_int ext_exp:15; - u_int ext_frach:16; - u_int ext_frachm; - u_int ext_fraclm; - u_int ext_fracl; -}; - /* * Floats whose exponent is in [1..INFNAN) (of whatever type) are * `normal'. Floats whose exponent is INFNAN are either Inf or NaN. @@ -116,12 +106,10 @@ struct ieee_ext { */ #define SNG_EXP_INFNAN 255 #define DBL_EXP_INFNAN 2047 -#define EXT_EXP_INFNAN 32767 #if 0 #define SNG_QUIETNAN (1 << 22) #define DBL_QUIETNAN (1 << 19) -#define EXT_QUIETNAN (1 << 15) #endif /* @@ -129,4 +117,3 @@ struct ieee_ext { */ #define SNG_EXP_BIAS 127 #define DBL_EXP_BIAS 1023 -#define EXT_EXP_BIAS 16383 diff --git a/sys/arch/sparc/include/ieee.h b/sys/arch/sparc/include/ieee.h index a66c9cc6f8c..31010a01238 100644 --- a/sys/arch/sparc/include/ieee.h +++ b/sys/arch/sparc/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.3 2003/06/02 23:27:54 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.4 2008/09/07 20:36:07 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.2 1994/11/20 20:53:10 deraadt Exp $ */ /* @@ -79,6 +79,8 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #ifdef notyet @@ -87,8 +89,21 @@ #endif #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 16 +#define EXT_FRACHMBITS 32 +#define EXT_FRACLMBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 112 +#define EXT_IMPLICIT_NBIT + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_fraclm; \ + (a)[2] = (uint32_t)(p)->ext_frachm; \ + (a)[3] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; diff --git a/sys/arch/sparc64/include/ieee.h b/sys/arch/sparc64/include/ieee.h index 8b60c991853..5c4b39e0d7e 100644 --- a/sys/arch/sparc64/include/ieee.h +++ b/sys/arch/sparc64/include/ieee.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee.h,v 1.2 2003/06/02 23:27:56 millert Exp $ */ +/* $OpenBSD: ieee.h,v 1.3 2008/09/07 20:36:07 martynas Exp $ */ /* $NetBSD: ieee.h,v 1.1.1.1 1998/06/20 04:58:51 eeh Exp $ */ /* @@ -79,6 +79,8 @@ #define SNG_FRACBITS 23 #define DBL_EXPBITS 11 +#define DBL_FRACHBITS 20 +#define DBL_FRACLBITS 32 #define DBL_FRACBITS 52 #ifdef notyet @@ -87,8 +89,21 @@ #endif #define EXT_EXPBITS 15 +#define EXT_FRACHBITS 16 +#define EXT_FRACHMBITS 32 +#define EXT_FRACLMBITS 32 +#define EXT_FRACLBITS 32 #define EXT_FRACBITS 112 +#define EXT_IMPLICIT_NBIT + +#define EXT_TO_ARRAY32(p, a) do { \ + (a)[0] = (uint32_t)(p)->ext_fracl; \ + (a)[1] = (uint32_t)(p)->ext_fraclm; \ + (a)[2] = (uint32_t)(p)->ext_frachm; \ + (a)[3] = (uint32_t)(p)->ext_frach; \ +} while(0) + struct ieee_single { u_int sng_sign:1; u_int sng_exp:8; |