(root)/
glibc-2.38/
sysdeps/
ieee754/
ldbl-96/
s_nexttowardf.c
       1  /* s_nexttowardf.c -- float version of s_nextafter.c.
       2   */
       3  
       4  /*
       5   * ====================================================
       6   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       7   *
       8   * Developed at SunPro, a Sun Microsystems, Inc. business.
       9   * Permission to use, copy, modify, and distribute this
      10   * software is freely granted, provided that this notice
      11   * is preserved.
      12   * ====================================================
      13   */
      14  
      15  #if defined(LIBM_SCCS) && !defined(lint)
      16  static char rcsid[] = "$NetBSD: $";
      17  #endif
      18  
      19  #include <errno.h>
      20  #include <math.h>
      21  #include <math-barriers.h>
      22  #include <math_private.h>
      23  #include <float.h>
      24  
      25  float __nexttowardf(float x, long double y)
      26  {
      27  	int32_t hx,ix,iy;
      28  	uint32_t hy,ly,esy;
      29  
      30  	GET_FLOAT_WORD(hx,x);
      31  	GET_LDOUBLE_WORDS(esy,hy,ly,y);
      32  	ix = hx&0x7fffffff;		/* |x| */
      33  	iy = esy&0x7fff;		/* |y| */
      34  
      35  	if((ix>0x7f800000) ||			/* x is nan */
      36  	   (iy>=0x7fff&&((hy|ly)!=0)))		/* y is nan */
      37  	   return x+y;
      38  	if((long double) x==y) return y;	/* x=y, return y */
      39  	if(ix==0) {				/* x == 0 */
      40  	    float u;
      41  	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
      42  	    u = math_opt_barrier (x);
      43  	    u = u * u;
      44  	    math_force_eval (u);		/* raise underflow flag */
      45  	    return x;
      46  	}
      47  	if(hx>=0) {				/* x > 0 */
      48  	    if(x > y) {				/* x -= ulp */
      49  		hx -= 1;
      50  	    } else {				/* x < y, x += ulp */
      51  		hx += 1;
      52  	    }
      53  	} else {				/* x < 0 */
      54  	    if(x < y) {				/* x -= ulp */
      55  		hx -= 1;
      56  	    } else {				/* x > y, x += ulp */
      57  		hx += 1;
      58  	    }
      59  	}
      60  	hy = hx&0x7f800000;
      61  	if(hy>=0x7f800000) {
      62  	  float u = x+x;			/* overflow  */
      63  	  math_force_eval (u);
      64  	  __set_errno (ERANGE);
      65  	}
      66  	if(hy<0x00800000) {
      67  	    float u = x*x;			/* underflow */
      68  	    math_force_eval (u);		/* raise underflow flag */
      69  	    __set_errno (ERANGE);
      70  	}
      71  	SET_FLOAT_WORD(x,hx);
      72  	return x;
      73  }
      74  weak_alias (__nexttowardf, nexttowardf)