svn commit: branches/uClibc-nptl/libm

vda at uclibc.org vda at uclibc.org
Fri Feb 6 01:57:01 UTC 2009


Author: vda
Date: 2009-02-06 01:57:00 +0000 (Fri, 06 Feb 2009)
New Revision: 25256

Log:
fix nextafterf. by Jie Zhang (jie.zhang AT analog.com)



Added:
   branches/uClibc-nptl/libm/s_nextafterf.c

Modified:
   branches/uClibc-nptl/libm/Makefile.in
   branches/uClibc-nptl/libm/float_wrappers.c


Changeset:
Modified: branches/uClibc-nptl/libm/Makefile.in
===================================================================
--- branches/uClibc-nptl/libm/Makefile.in	2009-02-06 01:56:25 UTC (rev 25255)
+++ branches/uClibc-nptl/libm/Makefile.in	2009-02-06 01:57:00 UTC (rev 25256)
@@ -61,7 +61,8 @@
 	s_asinh.c s_atan.c s_cbrt.c s_ceil.c s_copysign.c s_cos.c \
 	s_erf.c s_expm1.c s_fabs.c s_finite.c s_floor.c s_frexp.c \
 	s_ilogb.c s_ldexp.c s_lib_version.c s_lrint.c s_lround.c s_llround.c \
-	s_log1p.c s_logb.c s_matherr.c s_modf.c s_nextafter.c s_round.c \
+	s_log1p.c s_logb.c s_matherr.c s_modf.c s_nextafter.c \
+	s_nextafterf.c s_round.c \
 	s_rint.c s_scalbn.c s_signgam.c s_significand.c s_sin.c s_tan.c \
 	s_tanh.c s_trunc.c \
 	w_cabs.c \
@@ -76,7 +77,7 @@
 	expm1f.o fabsf.o fdimf.o floorf.o fmaf.o fmaxf.o fminf.o fmodf.o \
 	frexpf.o hypotf.o ilogbf.o ldexpf.o lgammaf.o llroundf.o log10f.o \
 	log1pf.o log2f.o logbf.o logf.o lrintf.o lroundf.o modff.o nearbyintf.o \
-	nextafterf.o powf.o remainderf.o remquof.o rintf.o roundf.o \
+	powf.o remainderf.o remquof.o rintf.o roundf.o \
 	scalblnf.o scalbnf.o sinf.o sinhf.o sqrtf.o tanf.o tanhf.o \
 	tgammaf.o truncf.o cargf.o llrintf.o scalbf.o gammaf.o significandf.o
 

Modified: branches/uClibc-nptl/libm/float_wrappers.c
===================================================================
--- branches/uClibc-nptl/libm/float_wrappers.c	2009-02-06 01:56:25 UTC (rev 25255)
+++ branches/uClibc-nptl/libm/float_wrappers.c	2009-02-06 01:57:00 UTC (rev 25256)
@@ -64,7 +64,6 @@
 float       logf(float);
 long        lroundf(float);
 float       modff(float, float *);
-float       nextafterf(float, float);
 float       powf(float, float);
 float       remainderf(float, float);
 float       rintf(float);
@@ -409,14 +408,6 @@
 #endif
 
 
-#ifdef L_nextafterf
-float nextafterf (float x, float y)
-{
-	return (float) nextafter( (double)x, (double)y );
-}
-#endif
-
-
 #ifdef L_nexttowardf
 float nexttowardf (float x, long double y)
 {

Added: branches/uClibc-nptl/libm/s_nextafterf.c
===================================================================
--- branches/uClibc-nptl/libm/s_nextafterf.c	                        (rev 0)
+++ branches/uClibc-nptl/libm/s_nextafterf.c	2009-02-06 01:57:00 UTC (rev 25256)
@@ -0,0 +1,103 @@
+/* s_nextafterf.c -- float version of s_nextafter.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian at 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"
+
+#ifndef math_opt_barrier
+# define math_opt_barrier(x) ({ __typeof (x) __x = x; __asm ("" : "+m" (__x)); __x; })
+# define math_force_eval(x)  __asm __volatile ("" : : "m" (x))
+#endif
+
+float nextafterf(float x, float y)
+{
+	int32_t hx, hy, ix, iy;
+
+	GET_FLOAT_WORD(hx, x);
+	GET_FLOAT_WORD(hy, y);
+	ix = hx & 0x7fffffff;		/* |x| */
+	iy = hy & 0x7fffffff;		/* |y| */
+
+	/* x is nan or y is nan? */
+	if ((ix > 0x7f800000) || (iy > 0x7f800000))
+		return x + y;
+
+	if (x == y)
+		return y;
+
+	if (ix == 0) { /* x == 0? */
+		float u;
+		/* return +-minsubnormal */
+		SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);
+		u = math_opt_barrier(x);
+		u = u * u;
+		math_force_eval(u); /* raise underflow flag */
+		return x;
+	}
+
+	if (hx >= 0) { /* x > 0 */
+		if (hx > hy) { /* x > y: x -= ulp */
+			hx -= 1;
+		} else { /* x < y: x += ulp */
+			hx += 1;
+		}
+	} else { /* x < 0 */
+		if (hy >= 0 || hx > hy) { /* x < y: x -= ulp */
+			hx -= 1;
+		} else { /* x > y: x += ulp */
+			hx += 1;
+		}
+	}
+	hy = hx & 0x7f800000;
+	if (hy >= 0x7f800000) {
+		x = x + x; /* overflow */
+//??		if (FLT_EVAL_METHOD != 0)
+//			asm ("" : "+m"(x));
+		return x; /* overflow */
+	}
+	if (hy < 0x00800000) {
+		float u = x * x; /* underflow */
+		math_force_eval(u); /* raise underflow flag */
+	}
+	SET_FLOAT_WORD(x, hx);
+	return x;
+}
+
+#if 0
+/* "testprog N a b"
+ * calculates a = nextafterf(a, b) and prints a as float
+ * and as raw bytes; repeats it N times.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+int main(int argc, char **argv)
+{
+        int cnt, i;
+        float a, b;
+        cnt = atoi(argv[1]);
+        a = strtod(argv[2], NULL);
+        b = strtod(argv[3], NULL);
+        while (cnt-- > 0) {
+                for (i = 0; i < sizeof(a); i++) {
+                        unsigned char c = ((char*)(&a))[i];
+                        printf("%x%x", (c >> 4), (c & 0xf));
+                }
+                printf(" %f\n", a);
+                a = nextafterf(a, b);
+        }
+        return 0;
+}
+#endif



More information about the uClibc-cvs mailing list