Mail Archives: djgpp-workers/2008/03/24/18:52:11
The patch below should provide an implementation of signbit.
To make the implementation easier to me I have added an union
for variables of type float of the same kind as exists for
double and long double.
As usual comments, suggestions, objections are welcome.
Regards,
Juan M. Guerrero
2008-03-23 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 -aprNU5 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-03-23 16:01:04 +0000
@@ -39,10 +39,16 @@ typedef struct {
} long_double_t;
typedef union
{
+ float f;
+ float_t ft;
+} _float_union_t;
+
+typedef union
+{
double d;
double_t dt;
} _double_union_t;
typedef union
diff -aprNU5 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-03-23 16:01:04 +0000
@@ -109,10 +109,15 @@ extern float __dj_nan;
#define fpclassify(x) ((sizeof(x)==sizeof(float))? __fpclassifyf(x) : \
(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)
#define isnormal(x) (fpclassify(x)==FP_NORMAL)
@@ -120,10 +125,13 @@ int __fpclassifyf(float) __attribute__(
int __fpclassifyd(double) __attribute__((const));
int __fpclassifyld(long double) __attribute__((const));
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
int __get_math_errhandling(void);
diff -aprNU5 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-03-23 16:02:22 +0000
@@ -1092,5 +1092,13 @@ character used by functions for converti
and to output, and function @code{strftime} uses the appropriate NLS
formats for @code{"%x"} and @code{"%X"} conversions.
@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 -aprNU5 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-03-23 16:01:04 +0000
@@ -10,10 +10,13 @@ SRC += nan.c
SRC += nanf.c
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
fpclassf.S: fp-asm.h
diff -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -aprNU5 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-03-23 16:01: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 -