1 
2 /*
3  * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 /* IEEE functions
28  *      nextafter(x,y)
29  *      return the next machine floating-point number of x in the
30  *      direction toward y.
31  *   Special cases:
32  */
33 
34 #include "fdlibm.h"
35 
36 #ifdef __STDC__
nextafter(double x,double y)37         double nextafter(double x, double y)
38 #else
39         double nextafter(x,y)
40         double x,y;
41 #endif
42 {
43         int     hx,hy,ix,iy;
44         unsigned lx,ly;
45 
46         hx = __HI(x);           /* high word of x */
47         lx = __LO(x);           /* low  word of x */
48         hy = __HI(y);           /* high word of y */
49         ly = __LO(y);           /* low  word of y */
50         ix = hx&0x7fffffff;             /* |x| */
51         iy = hy&0x7fffffff;             /* |y| */
52 
53         if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
54            ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
55            return x+y;
56         if(x==y) return x;              /* x=y, return x */
57         if((ix|lx)==0) {                        /* x == 0 */
58             __HI(x) = hy&0x80000000;    /* return +-minsubnormal */
59             __LO(x) = 1;
60             y = x*x;
61             if(y==x) return y; else return x;   /* raise underflow flag */
62         }
63         if(hx>=0) {                             /* x > 0 */
64             if(hx>hy||((hx==hy)&&(lx>ly))) {    /* x > y, x -= ulp */
65                 if(lx==0) hx -= 1;
66                 lx -= 1;
67             } else {                            /* x < y, x += ulp */
68                 lx += 1;
69                 if(lx==0) hx += 1;
70             }
71         } else {                                /* x < 0 */
72             if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
73                 if(lx==0) hx -= 1;
74                 lx -= 1;
75             } else {                            /* x > y, x += ulp */
76                 lx += 1;
77                 if(lx==0) hx += 1;
78             }
79         }
80         hy = hx&0x7ff00000;
81         if(hy>=0x7ff00000) return x+x;  /* overflow  */
82         if(hy<0x00100000) {             /* underflow */
83             y = x*x;
84             if(y!=x) {          /* raise underflow flag */
85                 __HI(y) = hx; __LO(y) = lx;
86                 return y;
87             }
88         }
89         __HI(x) = hx; __LO(x) = lx;
90         return x;
91 }
92