Mail Archives: djgpp-workers/2008/04/06/09:49:04
This is my latest patch for implementing signbit() macro and internal functions.
It is what I use in the latest libsupp. Suggestions, objections comments are
welcome.
Regards,
Juasn M. Guerrero
2008-04-06 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* src/include/math.h: Macro signbit added. Declaration for
__signbitd, __signbitf and __signbitld added.
* src/include/libc/ieee.h: Union _float_union_t added.
* src/libc/c99/math/makefile: Added sgnbitd.c, sgnbitf.c
and sgnbitld.c to the targets.
* src/libc/c99/math/sgnbitd.c: Double implementation of signbit.
* src/libc/c99/math/sgnbitd.txh: Info for __signbitd added
* src/libc/c99/math/sgnbitf.c: Float implementation of signbit.
* src/libc/c99/math/sgnbitf.txh: Info for __signbitf added
* src/libc/c99/math/sgnbitld.c: Long double implementation of signbit.
* src/libc/c99/math/sgnbitld.txh: Info for __signbitld added
* src/docs/kb/wc204.txi: Info about signbit added.
diff -aprNU3 djgpp.orig/include/libc/ieee.h djgpp/include/libc/ieee.h
--- djgpp.orig/include/libc/ieee.h 2003-06-30 20:38:14 +0000
+++ djgpp/include/libc/ieee.h 2008-04-06 15:10:04 +0000
@@ -41,6 +41,12 @@ typedef struct {
typedef union
{
+ float f;
+ float_t ft;
+} _float_union_t;
+
+typedef union
+{
double d;
double_t dt;
} _double_union_t;
diff -aprNU3 djgpp.orig/include/math.h djgpp/include/math.h
--- djgpp.orig/include/math.h 2003-11-21 21:19:42 +0000
+++ djgpp/include/math.h 2008-04-06 15:10:04 +0000
@@ -111,6 +111,12 @@ extern float __dj_nan;
(sizeof(x)==sizeof(double))? __fpclassifyd(x) : \
__fpclassifyld(x))
+#define signbit(x) (__extension__ ({__typeof__(x) __x = (x); \
+ (sizeof(__x) == sizeof(float)) ? __signbitf(__x) : \
+ (sizeof(__x) == sizeof(double)) ? __signbitd(__x) : \
+ __signbitld(__x); \
+ }))
+
#define isfinite(x) ((fpclassify(x) & (FP_NORMAL|FP_SUBNORMAL|FP_ZERO)) != 0)
#define isinf(x) (fpclassify(x)==FP_INFINITE)
#define isnan(x) (fpclassify(x)==FP_NAN)
@@ -122,6 +128,9 @@ int __fpclassifyld(long double) __attri
double nan(const char *);
float nanf(const char *);
long double nanl(const char *);
+int __signbitf(float x) __attribute__((const));
+int __signbitd(double x) __attribute__((const));
+int __signbitld(long double x) __attribute__((const));
#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
diff -aprNU3 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi 2005-05-11 20:06:08 +0000
+++ djgpp/src/docs/kb/wc204.txi 2008-04-06 15:10:04 +0000
@@ -1094,3 +1094,11 @@ formats for @code{"%x"} and @code{"%X"}
@pindex djasm AT r{, cr4 register}
@code{djasm} recognises the fourth control register, @code{cr4}.
+
+@findex signbit AT r{ added}
+@findex __signbitf AT r{ added}
+@findex __signbitd AT r{ added}
+@findex __signbitld AT r{ added}
+The C99 macro @code{signbit} and the supporting functions
+@code{__signbitf}, @code{__signbitd} and @code{__signbitld}
+were added.
diff -aprNU3 djgpp.orig/src/libc/c99/math/makefile djgpp/src/libc/c99/math/makefile
--- djgpp.orig/src/libc/c99/math/makefile 2003-11-21 21:19:42 +0000
+++ djgpp/src/libc/c99/math/makefile 2008-04-06 15:10:04 +0000
@@ -12,6 +12,9 @@ SRC += nanl.c
SRC += fpclassf.S
SRC += fpclassd.S
SRC += fpclassl.S
+SRC += sgnbitd.c
+SRC += sgnbitf.c
+SRC += sgnbitld.c
include $(TOP)/../makefile.inc
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitd.c djgpp/src/libc/c99/math/sgnbitd.c
--- djgpp.orig/src/libc/c99/math/sgnbitd.c 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitd.c 2008-04-06 15:10:04 +0000
@@ -0,0 +1,12 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+int
+__signbitd(double x)
+{
+ _double_union_t fp_value;
+
+ fp_value.d = x;
+ return (int)fp_value.dt.sign;
+}
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitd.txh djgpp/src/libc/c99/math/sgnbitd.txh
--- djgpp.orig/src/libc/c99/math/sgnbitd.txh 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitd.txh 2008-04-06 15:10:04 +0000
@@ -0,0 +1,33 @@
+@node __signbitd, math
+@findex __signbitd
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __signbitd(double @var{x});
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+
+printf("double value is %s.\n", (__signbitd(0.0)) ? "negative" : "positive");
+
+@end example
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitf.c djgpp/src/libc/c99/math/sgnbitf.c
--- djgpp.orig/src/libc/c99/math/sgnbitf.c 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitf.c 2008-04-06 15:10:04 +0000
@@ -0,0 +1,12 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+int
+__signbitf(float x)
+{
+ _float_union_t fp_value;
+
+ fp_value.f = x;
+ return (int)fp_value.ft.sign;
+}
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitf.txh djgpp/src/libc/c99/math/sgnbitf.txh
--- djgpp.orig/src/libc/c99/math/sgnbitf.txh 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitf.txh 2008-04-06 15:10:04 +0000
@@ -0,0 +1,33 @@
+@node __signbitf, math
+@findex __signbitf
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __signbitf(float @var{x});
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+
+printf("float value is %s.\n", (__signbitf(0.0F)) ? "negative" : "positive");
+
+@end example
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitld.c djgpp/src/libc/c99/math/sgnbitld.c
--- djgpp.orig/src/libc/c99/math/sgnbitld.c 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitld.c 2008-04-06 15:10:04 +0000
@@ -0,0 +1,12 @@
+/* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
+#include <math.h>
+#include <libc/ieee.h>
+
+int
+__signbitld(long double x)
+{
+ _longdouble_union_t fp_value;
+
+ fp_value.ld = x;
+ return (int)fp_value.ldt.sign;
+}
diff -aprNU3 djgpp.orig/src/libc/c99/math/sgnbitld.txh djgpp/src/libc/c99/math/sgnbitld.txh
--- djgpp.orig/src/libc/c99/math/sgnbitld.txh 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/sgnbitld.txh 2008-04-06 15:10:04 +0000
@@ -0,0 +1,33 @@
+@node __signbitld, math
+@findex __signbitld
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int __signbitld(long double @var{x});
+@end example
+
+@subheading Description
+
+Returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+You should use the type generic macro @code{signbit} (@pxref{signbit})
+instead of this function.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+
+printf("long double value is %s.\n", (__signbitld(0.0L)) ? "negative" : "positive");
+
+@end example
diff -aprNU3 djgpp.orig/src/libc/c99/math/signbit.txh djgpp/src/libc/c99/math/signbit.txh
--- djgpp.orig/src/libc/c99/math/signbit.txh 1970-01-01 00:00:00 +0000
+++ djgpp/src/libc/c99/math/signbit.txh 2008-04-06 15:10:04 +0000
@@ -0,0 +1,36 @@
+@node signbit, math
+@findex signbit
+@subheading Syntax
+
+@example
+#include <math.h>
+
+int signbit(@var{x});
+@end example
+
+@subheading Description
+
+The macro @code{signbit} returns 0 if the sign of the mantissa of the floating
+point number @var{x} is positive else it returns non-zero.
+
+@subheading Return Value
+
+zero for positive floating point numbers;
+non-zero for negative floating point numbers.
+
+@subheading Portability
+
+@portability !ansi-c89, ansi-c99
+
+@subheading Example
+
+@example
+float f = 1;
+double d = INFINITY;
+long double ld = NAN;
+
+printf("value is %s.\n", (signbit(f)) ? "negative" : "positive");
+printf("value is %s.\n", (signbit(d)) ? "negative" : "positive");
+printf("value is %s.\n", (signbit(ld)) ? "negative" : "positive");
+
+@end example
- Raw text -