s_nexttowardf.c revision 143218
13229Spst/* 23229Spst * ==================================================== 318471Swosch * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 418471Swosch * 53229Spst * Developed at SunPro, a Sun Microsystems, Inc. business. 63229Spst * Permission to use, copy, modify, and distribute this 73229Spst * software is freely granted, provided that this notice 83229Spst * is preserved. 93229Spst * ==================================================== 103229Spst */ 113229Spst 123229Spst#ifndef lint 133229Spststatic char rcsid[] = "$FreeBSD: head/lib/msun/src/s_nexttowardf.c 143218 2005-03-07 04:57:38Z das $"; 143229Spst#endif 153229Spst 163229Spst#include <float.h> 173229Spst 183229Spst#include "fpmath.h" 193229Spst#include "math.h" 203229Spst#include "math_private.h" 213229Spst 223229Spst#define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) 233229Spst 243229Spstfloat 253229Spstnexttowardf(float x, long double y) 263229Spst{ 273229Spst union IEEEl2bits uy; 283229Spst volatile float t; 293229Spst int32_t hx,ix; 303229Spst 313229Spst GET_FLOAT_WORD(hx,x); 323229Spst ix = hx&0x7fffffff; /* |x| */ 333229Spst uy.e = y; 343229Spst 353229Spst if((ix>0x7f800000) || 363229Spst (uy.bits.exp == LDBL_INFNAN_EXP && 373229Spst ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0)) 383229Spst return x+y; /* x or y is nan */ 393229Spst if(x==y) return (float)y; /* x=y, return y */ 403229Spst if(ix==0) { /* x == 0 */ 413229Spst SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal */ 423229Spst t = x*x; 433229Spst if(t==x) return t; else return x; /* raise underflow flag */ 443229Spst } 453229Spst if(hx>=0 ^ x < y) /* x -= ulp */ 463229Spst hx -= 1; 473229Spst else /* x += ulp */ 483229Spst hx += 1; 493229Spst ix = hx&0x7f800000; 503229Spst if(ix>=0x7f800000) return x+x; /* overflow */ 513229Spst if(ix<0x00800000) { /* underflow */ 523229Spst t = x*x; 533229Spst if(t!=x) { /* raise underflow flag */ 543229Spst SET_FLOAT_WORD(y,hx); 553229Spst return y; 563229Spst } 573229Spst } 583229Spst SET_FLOAT_WORD(x,hx); 593229Spst return x; 603229Spst} 613229Spst