Date: Thu, 9 May 2002 03:10:03 -0700 (PDT) From: David Schultz <dschultz@uclink.Berkeley.EDU> To: standards@FreeBSD.org Subject: Re: misc/23103: <math.h> lacks many ISO C99 features (NAN, isfinite,...) Message-ID: <200205091010.g49AA3t98744@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR misc/23103; it has been noted by GNATS. From: David Schultz <dschultz@uclink.Berkeley.EDU> To: freebsd-gnats-submit@FreeBSD.org, freebsd-standards@FreeBSD.org Cc: Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> Subject: Re: misc/23103: <math.h> lacks many ISO C99 features (NAN, isfinite,...) Date: Thu, 9 May 2002 03:09:26 -0700 Thus spake Gerald Pfeifer: > <math.h> AKA /usr/include/math.h lacks a couple of features > required by ISO C99. ISO compliant programs will thus fail to > compile; one (more or less) prominent one is Wine. > > Features missing include macros FP_INFINITE, FP_NAN, FP_NORMAL, > FP_SUBNORMAL, FP_ZERO, fpclassify(), and isfinite(). I've made some patches to add most of these features for i386. The remaining ones are mostly trivial extensions to the ones I've already added. I would just like to get some assurance that I'm on the right track with these changes before I go ahead and write the rest of the C99 stuff for all supported architectures. Notes: - Some of the symbolic constants in math.h are architecture-dependant, and I don't know if anything special needs to be done about this. Architecture-dependent assumptions are: o ints are 32 bits FP_ILOG* o doubles are 64-bit IEEE 754's DECIMAL_DIG o `long double' is an appropriate choice for FLT_EVAL_METHOD float_t and double_t - The necessary support needs to be added to libc in all architectures before the math.h changes can be committed. The i386 code I wrote should work fine on any architecture on which floats, doubles, and long doubles have 32, 64, and 80 bits of precision, respectively, but fpclassify() can be done more efficiently on 64-bit architectures. Please CC me any responses; I'm not subscribed to -standards. Here are the patches: Index: math.h =================================================================== RCS file: /home/ncvs/src/lib/msun/src/math.h,v retrieving revision 1.8.2.2 diff -u -r1.8.2.2 math.h --- math.h 2001/11/23 16:16:18 1.8.2.2 +++ math.h 2002/05/09 09:35:02 @@ -21,7 +21,39 @@ * ANSI/POSIX */ extern char __infinity[]; +extern char __infinity_f[]; +extern char __infinity_l[]; +extern char __nan[]; #define HUGE_VAL (*(double *) __infinity) +#define HUGE_VALF (*(float *) __infinity_f) +#define HUGE_VALL (*(long double *) __infinity_l) +#define INFINITY HUGE_VALF +#define NAN (*(float *) __nan) +#define FP_ILOGB0 (-0x7fffffff - 1) /* INT_MIN */ +#define FP_ILOGBNAN 0x7fffffff /* INT_MAX */ +#define DECIMAL_DIG 15 + +#define FLT_EVAL_METHOD 2 +typedef long double float_t; +typedef long double double_t; + +/* Symbolic constants to classify floating point numbers */ +#define FP_INFINITE 1 +#define FP_NAN 2 +#define FP_NORMAL 3 +#define FP_SUBNORMAL 4 +#define FP_ZERO 5 +#define fpclassify(x) \ + ((sizeof (x) == sizeof (float)) ? \ + __fpclassifyf(x) \ + : (sizeof (x) == sizeof (double)) ? \ + __fpclassifyd(x) \ + : __fpclassifyl(x)) + +/* XXX missing: C99 7.12.7 FP_FAST_FMA* + * need to add or fix up isfinite(), isinf(), isnan(), + * isnormal(), signbit() + */ /* * XOPEN/SVID Index: Makefile.inc =================================================================== RCS file: /home/ncvs/src/lib/libc/i386/gen/Makefile.inc,v retrieving revision 1.10.2.1 diff -u -r1.10.2.1 Makefile.inc --- Makefile.inc 2001/02/07 00:12:45 1.10.2.1 +++ Makefile.inc 2002/05/09 09:57:13 @@ -1,5 +1,5 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD: src/lib/libc/i386/gen/Makefile.inc,v 1.10.2.1 2001/02/07 00:12:45 peter Exp $ -SRCS+= _setjmp.S alloca.S fabs.S frexp.c infinity.c isinf.c ldexp.c modf.S \ - rfork_thread.S setjmp.S sigsetjmp.S +SRCS+= _setjmp.S alloca.S fabs.S fpclassify.c frexp.c infinity.c isinf.c \ + ldexp.c modf.S rfork_thread.S setjmp.S sigsetjmp.S Index: infinity.c =================================================================== RCS file: /home/ncvs/src/lib/libc/i386/gen/infinity.c,v retrieving revision 1.5 diff -u -u -r1.5 infinity.c --- infinity.c 1999/08/27 23:59:21 1.5 +++ infinity.c 2002/05/09 09:44:05 @@ -7,3 +7,8 @@ /* bytes for +Infinity on a 387 */ char __infinity[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +char __infinity_f[] = { 0, 0, 0x80, 0x7f }; +char __infinity_l[] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f, 0, 0 }; + +/* bytes for NaN */ +char __nan[] = { 0, 0, 0xc0, 0x7f }; --- /dev/null Thu May 9 02:44:57 2002 +++ fpclassify.c Wed May 8 06:30:05 2002 @@ -0,0 +1,81 @@ +/* + * $FreeBSD: $ + */ + +#include <sys/types.h> +#include <math.h> + +int +__fpclassifyf(f) + float f; +{ + register union flt2d { + float fv; + u_int32_t dv; + } u; + + u.fv = f; + u.dv &= 0x7fffffff; + if (u.dv == 0) + return FP_ZERO; + else if (u.dv < 0x00800000) + return FP_SUBNORMAL; + else if (u.dv == 0x7f800000) + return FP_INFINITE; + else if (u.dv > 0x7f800000) + return FP_NAN; + else + return FP_NORMAL; +} + +int +__fpclassifyd(d) + double d; +{ + register struct IEEEdp { + u_int manl : 32; + u_int manh : 20; + u_int exp : 11; + u_int sign : 1; + } *p = (struct IEEEdp *)&d; + + if (p->exp == 0) { + if ((p->manl | p->manh) == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } else if (p->exp == 2047) { + if ((p->manl | p->manh) == 0) + return FP_INFINITE; + else + return FP_NAN; + } else + return FP_NORMAL; +} + +int +__fpclassifyl(l) + long double l; +{ + register struct IEEElp { + u_int manl : 32; + u_int manh : 31; + u_int exp : 16; + u_int sign : 1; + u_int junk : 16; + } *p = (struct IEEElp *)&l; + + if (p->exp == 0) { + if ((p->manl | p->manh) == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } else if (p->exp == 32767) { + if ((p->manl | p->manh) == 0) + return FP_INFINITE; + else + return FP_NAN; + } else + return FP_NORMAL; + +} To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200205091010.g49AA3t98744>