home *** CD-ROM | disk | FTP | other *** search
/ Game Zone - 1,000+ Games / GAMEZONE.BIN / Programs / PALM / Oh-One / src / s_nextafter.c < prev    next >
C/C++ Source or Header  |  1997-03-22  |  2KB  |  85 lines

  1. /* @(#)s_nextafter.c 5.1 93/09/24 */
  2. /*
  3.  * ====================================================
  4.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5.  *
  6.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software is freely granted, provided that this notice
  9.  * is preserved.
  10.  * ====================================================
  11.  */
  12.  
  13. #if defined(LIBM_SCCS) && !defined(lint)
  14. static char rcsid[] = "$NetBSD: s_nextafter.c,v 1.8 1995/05/10 20:47:58 jtc Exp $";
  15. #endif
  16.  
  17. /* IEEE functions
  18.  *    nextafter(x,y)
  19.  *    return the next machine floating-point number of x in the
  20.  *    direction toward y.
  21.  *   Special cases:
  22.  */
  23.  
  24. #include "math.h"
  25. #include "math_private.h"
  26.  
  27. #ifdef __STDC__
  28.     double __nextafter(double x, double y)
  29. #else
  30.     double __nextafter(x,y)
  31.     double x,y;
  32. #endif
  33. {
  34.     int32_t hx,hy,ix,iy;
  35.     u_int32_t lx,ly;
  36.  
  37.     EXTRACT_WORDS(hx,lx,x);
  38.     EXTRACT_WORDS(hy,ly,y);
  39.     ix = hx&0x7fffffff;        /* |x| */
  40.     iy = hy&0x7fffffff;        /* |y| */
  41.  
  42.     if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
  43.        ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
  44.        return x+y;
  45.     if(x==y) return y;        /* x=y, return y */
  46.     if((ix|lx)==0) {            /* x == 0 */
  47.         INSERT_WORDS(x,hy&0x80000000,1);    /* return +-minsubnormal */
  48.         y = x*x;
  49.         if(y==x) return y; else return x;    /* raise underflow flag */
  50.     }
  51.     if(hx>=0) {                /* x > 0 */
  52.         if(hx>hy||((hx==hy)&&(lx>ly))) {    /* x > y, x -= ulp */
  53.         if(lx==0) hx -= 1;
  54.         lx -= 1;
  55.         } else {                /* x < y, x += ulp */
  56.         lx += 1;
  57.         if(lx==0) hx += 1;
  58.         }
  59.     } else {                /* x < 0 */
  60.         if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
  61.         if(lx==0) hx -= 1;
  62.         lx -= 1;
  63.         } else {                /* x > y, x += ulp */
  64.         lx += 1;
  65.         if(lx==0) hx += 1;
  66.         }
  67.     }
  68.     hy = hx&0x7ff00000;
  69.     if(hy>=0x7ff00000) return x+x;    /* overflow  */
  70.     if(hy<0x00100000) {        /* underflow */
  71.         y = x*x;
  72.         if(y!=x) {        /* raise underflow flag */
  73.             INSERT_WORDS(y,hx,lx);
  74.         return y;
  75.         }
  76.     }
  77.     INSERT_WORDS(x,hx,lx);
  78.     return x;
  79. }
  80. weak_alias (__nextafter, nextafter)
  81. #ifdef NO_LONG_DOUBLE
  82. strong_alias (__nextafter, __nextafterl)
  83. weak_alias (__nextafter, nextafterl)
  84. #endif
  85.