s_nextafter.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       s_nextafter.c (1958B)
       ---
            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 #ifndef lint
           14 static char rcsid[] = "$FreeBSD: src/lib/msun/src/s_nextafter.c,v 1.9 2005/01/23 22:56:08 das 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 double
           28 nextafter(double x, double y)
           29 {
           30         int32_t hx,hy,ix,iy;
           31         u_int32_t lx,ly;
           32 
           33         EXTRACT_WORDS(hx,lx,x);
           34         EXTRACT_WORDS(hy,ly,y);
           35         ix = hx&0x7fffffff;                /* |x| */
           36         iy = hy&0x7fffffff;                /* |y| */
           37 
           38         if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
           39            ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
           40            return x+y;
           41         if(x==y) return y;                /* x=y, return y */
           42         if((ix|lx)==0) {                        /* x == 0 */
           43             INSERT_WORDS(x,hy&0x80000000,1);        /* return +-minsubnormal */
           44             y = x*x;
           45             if(y==x) return y; else return x;        /* raise underflow flag */
           46         }
           47         if(hx>=0) {                                /* x > 0 */
           48             if(hx>hy||((hx==hy)&&(lx>ly))) {        /* x > y, x -= ulp */
           49                 if(lx==0) hx -= 1;
           50                 lx -= 1;
           51             } else {                                /* x < y, x += ulp */
           52                 lx += 1;
           53                 if(lx==0) hx += 1;
           54             }
           55         } else {                                /* x < 0 */
           56             if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
           57                 if(lx==0) hx -= 1;
           58                 lx -= 1;
           59             } else {                                /* x > y, x += ulp */
           60                 lx += 1;
           61                 if(lx==0) hx += 1;
           62             }
           63         }
           64         hy = hx&0x7ff00000;
           65         if(hy>=0x7ff00000) return x+x;        /* overflow  */
           66         if(hy<0x00100000) {                /* underflow */
           67             y = x*x;
           68             if(y!=x) {                /* raise underflow flag */
           69                 INSERT_WORDS(y,hx,lx);
           70                 return y;
           71             }
           72         }
           73         INSERT_WORDS(x,hx,lx);
           74         return x;
           75 }