• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * This file is based on work under the following copyright and permission
16  * notice:
17  *
18  *     Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19  *
20  *     Developed at SunSoft, a Sun Microsystems, Inc. business.
21  *     Permission to use, copy, modify, and distribute this
22  *     software is freely granted, provided that this notice
23  *     is preserved.
24  *
25  *     @(#)s_nextafter.c 1.3 95/01/18
26  */
27 
28 #include "jerry-libm-internal.h"
29 
30 double
nextafter(double x,double y)31 nextafter (double x,
32            double y)
33 {
34   int hx, hy, ix, iy;
35   unsigned lx, ly;
36   double_accessor ret;
37 
38   hx = __HI (x); /* high word of x */
39   lx = __LO (x); /* low  word of x */
40   hy = __HI (y); /* high word of y */
41   ly = __LO (y); /* low  word of y */
42   ix = hx & 0x7fffffff; /* |x| */
43   iy = hy & 0x7fffffff; /* |y| */
44 
45   if (((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0)     /* x is nan */
46       || ((iy >= 0x7ff00000) && ((iy - 0x7ff00000) | ly) != 0)) /* y is nan */
47   {
48     return x + y;
49   }
50 
51   if (x == y)
52   {
53     return x; /* x=y, return x */
54   }
55 
56   if ((ix | lx) == 0)
57   { /* x == 0 */
58     ret.as_int.hi = hy & 0x80000000; /* return +-minsubnormal */
59     ret.as_int.lo = 1;
60     y = ret.dbl * ret.dbl;
61     if (y == ret.dbl)
62     {
63       return y;
64     }
65     else
66     {
67       return ret.dbl; /* raise underflow flag */
68     }
69   }
70 
71   if (hx >= 0)
72   { /* x > 0 */
73     if (hx > hy || ((hx == hy) && (lx > ly)))
74     { /* x > y, x -= ulp */
75       if (lx == 0)
76       {
77         hx -= 1;
78       }
79 
80       lx -= 1;
81     }
82     else
83     { /* x < y, x += ulp */
84       lx += 1;
85 
86       if (lx == 0)
87       {
88         hx += 1;
89       }
90     }
91   }
92   else
93   { /* x < 0 */
94     if (hy >= 0 || hx > hy || ((hx == hy) && (lx > ly)))
95     { /* x < y, x -= ulp */
96       if (lx == 0)
97       {
98         hx -= 1;
99       }
100 
101       lx -= 1;
102     }
103     else
104     { /* x > y, x += ulp */
105       lx += 1;
106 
107       if (lx == 0)
108       {
109         hx += 1;
110       }
111     }
112   }
113 
114   hy = hx & 0x7ff00000;
115 
116   if (hy >= 0x7ff00000)
117   {
118     return x + x; /* overflow */
119   }
120 
121   if (hy < 0x00100000)
122   { /* underflow */
123     y = x * x;
124     if (y != x)
125     { /* raise underflow flag */
126       ret.as_int.hi = hx;
127       ret.as_int.lo = lx;
128       return ret.dbl;
129     }
130   }
131 
132   ret.as_int.hi = hx;
133   ret.as_int.lo = lx;
134   return ret.dbl;
135 } /* nextafter */
136