diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog index ac21c8c99..8c307a5af 100644 --- a/winsup/mingw/ChangeLog +++ b/winsup/mingw/ChangeLog @@ -1,7 +1,16 @@ +2005-05-09 Danny Smith + + * mingwex/math/nextafterf.c (nextafterf): Correct + handling of -0.0. + * mingwex/math/nextafterl.c: New file. + * mingwex/Makefile.in (MATH_DISTFILES): Add nextafterl.c. + (MATH_OBJS): Add nextafterl.o. + * include/math.h (nextafterl): Uncomment prototype. + 2005-05-08 Danny Smith * mingwex/math/erfl.c: New file. - * mingwex/Makefile.i (MATH_DISTFILES): Add erfl.c. + * mingwex/Makefile.in (MATH_DISTFILES): Add erfl.c. (MATH_OBJS): Add erfl.o. * include/math.h (erfl, erfcl): Uncomment prototypes. diff --git a/winsup/mingw/include/math.h b/winsup/mingw/include/math.h index 751fa9509..9f1531dd7 100644 --- a/winsup/mingw/include/math.h +++ b/winsup/mingw/include/math.h @@ -721,8 +721,7 @@ extern long double __cdecl nanl(const char *tagp); /* 7.12.11.3 */ extern double __cdecl nextafter (double, double); /* in libmoldname.a */ extern float __cdecl nextafterf (float, float); -/* TODO: Not yet implemented */ -/* extern long double __cdecl nextafterl (long double, long double); */ +extern long double __cdecl nextafterl (long double, long double); /* 7.12.11.4 The nexttoward functions: TODO */ diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in index 8bfebc533..289a44c54 100644 --- a/winsup/mingw/mingwex/Makefile.in +++ b/winsup/mingw/mingwex/Makefile.in @@ -54,7 +54,7 @@ MATH_DISTFILES = \ log10f.S log10l.S log1p.S log1pf.S log1pl.S log2.S log2f.S \ log2l.S logb.c logbf.c logbl.c logf.S logl.S lrint.c lrintf.c \ lrintl.c lround.c lroundf.c lroundl.c modff.c modfl.c \ - nearbyint.S nearbyintf.S nearbyintl.S nextafterf.c \ + nearbyint.S nearbyintf.S nearbyintl.S nextafterf.c nextafterl.c \ powf.c powi.c powif.c powil.c powl.c \ remainder.S remainderf.S remainderl.S remquo.S \ remquof.S remquol.S rint.c rintf.c rintl.c round.c roundf.c \ @@ -146,7 +146,7 @@ MATH_OBJS = \ log10f.o log10l.o log1p.o log1pf.o log1pl.o log2.o log2f.o \ log2l.o logb.o logbf.o logbl.o logf.o logl.o lrint.o lrintf.o \ lrintl.o lround.o lroundf.o lroundl.o modff.o modfl.o \ - nearbyint.o nearbyintf.o nearbyintl.o nextafterf.o \ + nearbyint.o nearbyintf.o nearbyintl.o nextafterf.o nextafterl.o \ powf.o powi.o powif.o powil.o powl.o \ remainder.o remainderf.o remainderl.o remquo.o \ remquof.o remquol.o rint.o rintf.o rintl.o round.o roundf.o \ diff --git a/winsup/mingw/mingwex/math/nextafterf.c b/winsup/mingw/mingwex/math/nextafterf.c index ac1fbee26..47309a027 100644 --- a/winsup/mingw/mingwex/math/nextafterf.c +++ b/winsup/mingw/mingwex/math/nextafterf.c @@ -11,17 +11,15 @@ nextafterf (float x, float y) if (isnan (y) || isnan (x)) return x + y; if (x == y ) - return x; + /* nextafter (0.0, -O.0) should return -0.0. */ + return y; u.f = x; - if (u.i == 0u) + if (x == 0.0F) { - if (y > 0.0F) - u.i = 1; - else - u.i = 0x80000001; - return u.f; + u.i = 1; + return y > 0.0F ? u.f : -u.f; } - if (((x > 0.0F) ^ (y > x)) == 0) + if (((x > 0.0F) ^ (y > x)) == 0) u.i++; else u.i--; diff --git a/winsup/mingw/mingwex/math/nextafterl.c b/winsup/mingw/mingwex/math/nextafterl.c new file mode 100755 index 000000000..84be44fb2 --- /dev/null +++ b/winsup/mingw/mingwex/math/nextafterl.c @@ -0,0 +1,61 @@ +/* + nextafterl.c + Contributed by Danny Smith + No copyright claimed, absolutely no warranties. + + 2005-05-09 +*/ + +#include + +long double +nextafterl (long double x, long double y) +{ + union { + long double ld; + struct { + unsigned long long mantissa; + unsigned short expn; + unsigned short pad; + } __attribute__ ((packed)) parts; + } u; + + /* The normal bit is explicit for long doubles, unlike + float and double. */ + static const unsigned long long normal_bit = 0x8000000000000000ull; + + if (isnan (y) || isnan (x)) + return x + y; + + if (x == y ) + /* nextafter (0.0, -O.0) should return -0.0. */ + return y; + + u.ld = x; + if (x == 0.0L) + { + u.parts.mantissa = 1ull; + return y > 0.0L ? u.ld : -u.ld; + } + + if (((x > 0.0L) ^ (y > x)) == 0) + { + u.parts.mantissa++; + if ((u.parts.mantissa & ~normal_bit) == 0ull) + u.parts.expn++; + } + else + { + if ((u.parts.mantissa & ~normal_bit) == 0ull) + u.parts.expn--; + u.parts.mantissa--; + } + + /* If we have updated the expn of a normal number, + or moved from denormal to normal, [re]set the normal bit. */ + + if (u.parts.expn & 0x7fff) + u.parts.mantissa |= normal_bit; + + return u.ld; +}