Module Name: src Committed By: christos Date: Sat Feb 9 19:39:01 UTC 2013
Added Files: src/lib/libm/src: s_nexttowardf.c Log Message: one more To generate a diff of this commit: cvs rdiff -u -r0 -r1.1 src/lib/libm/src/s_nexttowardf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Added files: Index: src/lib/libm/src/s_nexttowardf.c diff -u /dev/null src/lib/libm/src/s_nexttowardf.c:1.1 --- /dev/null Sat Feb 9 14:39:01 2013 +++ src/lib/libm/src/s_nexttowardf.c Sat Feb 9 14:39:01 2013 @@ -0,0 +1,65 @@ +/* $NetBSD: s_nexttowardf.c,v 1.1 2013/02/09 19:39:01 christos Exp $ */ + +/* + * ==================================================== + * 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 <sys/cdefs.h> +#if 0 +__FBSDID("$FreeBSD: src/lib/msun/src/s_nexttowardf.c,v 1.3 2011/02/10 07:38:38 das Exp $"); +#else +__RCSID("$NetBSD: s_nexttowardf.c,v 1.1 2013/02/09 19:39:01 christos Exp $"); +#endif + +#include <float.h> + +#include "fpmath.h" +#include "math.h" +#include "math_private.h" + +#define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) + +float +nexttowardf(float x, long double y) +{ + union IEEEl2bits uy; + volatile float t; + int32_t hx,ix; + + GET_FLOAT_WORD(hx,x); + ix = hx&0x7fffffff; /* |x| */ + uy.e = y; + + if((ix>0x7f800000) || + (uy.bits.exp == LDBL_INFNAN_EXP && + ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) + return x+y; /* x or y is nan */ + if(x==y) return (float)y; /* x=y, return y */ + if(ix==0) { /* x == 0 */ + SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal */ + t = x*x; + if(t==x) return t; else return x; /* raise underflow flag */ + } + if(hx>=0 ^ x < y) /* x -= ulp */ + hx -= 1; + else /* x += ulp */ + hx += 1; + ix = hx&0x7f800000; + if(ix>=0x7f800000) return x+x; /* overflow */ + if(ix<0x00800000) { /* underflow */ + t = x*x; + if(t!=x) { /* raise underflow flag */ + SET_FLOAT_WORD(x,hx); + return x; + } + } + SET_FLOAT_WORD(x,hx); + return x; +}