1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci * 15425bb815Sopenharmony_ci * This file is based on work under the following copyright and permission 16425bb815Sopenharmony_ci * notice: 17425bb815Sopenharmony_ci * 18425bb815Sopenharmony_ci * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 19425bb815Sopenharmony_ci * 20425bb815Sopenharmony_ci * Developed at SunSoft, a Sun Microsystems, Inc. business. 21425bb815Sopenharmony_ci * Permission to use, copy, modify, and distribute this 22425bb815Sopenharmony_ci * software is freely granted, provided that this notice 23425bb815Sopenharmony_ci * is preserved. 24425bb815Sopenharmony_ci * 25425bb815Sopenharmony_ci * @(#)s_nextafter.c 1.3 95/01/18 26425bb815Sopenharmony_ci */ 27425bb815Sopenharmony_ci 28425bb815Sopenharmony_ci#include "jerry-libm-internal.h" 29425bb815Sopenharmony_ci 30425bb815Sopenharmony_cidouble 31425bb815Sopenharmony_cinextafter (double x, 32425bb815Sopenharmony_ci double y) 33425bb815Sopenharmony_ci{ 34425bb815Sopenharmony_ci int hx, hy, ix, iy; 35425bb815Sopenharmony_ci unsigned lx, ly; 36425bb815Sopenharmony_ci double_accessor ret; 37425bb815Sopenharmony_ci 38425bb815Sopenharmony_ci hx = __HI (x); /* high word of x */ 39425bb815Sopenharmony_ci lx = __LO (x); /* low word of x */ 40425bb815Sopenharmony_ci hy = __HI (y); /* high word of y */ 41425bb815Sopenharmony_ci ly = __LO (y); /* low word of y */ 42425bb815Sopenharmony_ci ix = hx & 0x7fffffff; /* |x| */ 43425bb815Sopenharmony_ci iy = hy & 0x7fffffff; /* |y| */ 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ci if (((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0) /* x is nan */ 46425bb815Sopenharmony_ci || ((iy >= 0x7ff00000) && ((iy - 0x7ff00000) | ly) != 0)) /* y is nan */ 47425bb815Sopenharmony_ci { 48425bb815Sopenharmony_ci return x + y; 49425bb815Sopenharmony_ci } 50425bb815Sopenharmony_ci 51425bb815Sopenharmony_ci if (x == y) 52425bb815Sopenharmony_ci { 53425bb815Sopenharmony_ci return x; /* x=y, return x */ 54425bb815Sopenharmony_ci } 55425bb815Sopenharmony_ci 56425bb815Sopenharmony_ci if ((ix | lx) == 0) 57425bb815Sopenharmony_ci { /* x == 0 */ 58425bb815Sopenharmony_ci ret.as_int.hi = hy & 0x80000000; /* return +-minsubnormal */ 59425bb815Sopenharmony_ci ret.as_int.lo = 1; 60425bb815Sopenharmony_ci y = ret.dbl * ret.dbl; 61425bb815Sopenharmony_ci if (y == ret.dbl) 62425bb815Sopenharmony_ci { 63425bb815Sopenharmony_ci return y; 64425bb815Sopenharmony_ci } 65425bb815Sopenharmony_ci else 66425bb815Sopenharmony_ci { 67425bb815Sopenharmony_ci return ret.dbl; /* raise underflow flag */ 68425bb815Sopenharmony_ci } 69425bb815Sopenharmony_ci } 70425bb815Sopenharmony_ci 71425bb815Sopenharmony_ci if (hx >= 0) 72425bb815Sopenharmony_ci { /* x > 0 */ 73425bb815Sopenharmony_ci if (hx > hy || ((hx == hy) && (lx > ly))) 74425bb815Sopenharmony_ci { /* x > y, x -= ulp */ 75425bb815Sopenharmony_ci if (lx == 0) 76425bb815Sopenharmony_ci { 77425bb815Sopenharmony_ci hx -= 1; 78425bb815Sopenharmony_ci } 79425bb815Sopenharmony_ci 80425bb815Sopenharmony_ci lx -= 1; 81425bb815Sopenharmony_ci } 82425bb815Sopenharmony_ci else 83425bb815Sopenharmony_ci { /* x < y, x += ulp */ 84425bb815Sopenharmony_ci lx += 1; 85425bb815Sopenharmony_ci 86425bb815Sopenharmony_ci if (lx == 0) 87425bb815Sopenharmony_ci { 88425bb815Sopenharmony_ci hx += 1; 89425bb815Sopenharmony_ci } 90425bb815Sopenharmony_ci } 91425bb815Sopenharmony_ci } 92425bb815Sopenharmony_ci else 93425bb815Sopenharmony_ci { /* x < 0 */ 94425bb815Sopenharmony_ci if (hy >= 0 || hx > hy || ((hx == hy) && (lx > ly))) 95425bb815Sopenharmony_ci { /* x < y, x -= ulp */ 96425bb815Sopenharmony_ci if (lx == 0) 97425bb815Sopenharmony_ci { 98425bb815Sopenharmony_ci hx -= 1; 99425bb815Sopenharmony_ci } 100425bb815Sopenharmony_ci 101425bb815Sopenharmony_ci lx -= 1; 102425bb815Sopenharmony_ci } 103425bb815Sopenharmony_ci else 104425bb815Sopenharmony_ci { /* x > y, x += ulp */ 105425bb815Sopenharmony_ci lx += 1; 106425bb815Sopenharmony_ci 107425bb815Sopenharmony_ci if (lx == 0) 108425bb815Sopenharmony_ci { 109425bb815Sopenharmony_ci hx += 1; 110425bb815Sopenharmony_ci } 111425bb815Sopenharmony_ci } 112425bb815Sopenharmony_ci } 113425bb815Sopenharmony_ci 114425bb815Sopenharmony_ci hy = hx & 0x7ff00000; 115425bb815Sopenharmony_ci 116425bb815Sopenharmony_ci if (hy >= 0x7ff00000) 117425bb815Sopenharmony_ci { 118425bb815Sopenharmony_ci return x + x; /* overflow */ 119425bb815Sopenharmony_ci } 120425bb815Sopenharmony_ci 121425bb815Sopenharmony_ci if (hy < 0x00100000) 122425bb815Sopenharmony_ci { /* underflow */ 123425bb815Sopenharmony_ci y = x * x; 124425bb815Sopenharmony_ci if (y != x) 125425bb815Sopenharmony_ci { /* raise underflow flag */ 126425bb815Sopenharmony_ci ret.as_int.hi = hx; 127425bb815Sopenharmony_ci ret.as_int.lo = lx; 128425bb815Sopenharmony_ci return ret.dbl; 129425bb815Sopenharmony_ci } 130425bb815Sopenharmony_ci } 131425bb815Sopenharmony_ci 132425bb815Sopenharmony_ci ret.as_int.hi = hx; 133425bb815Sopenharmony_ci ret.as_int.lo = lx; 134425bb815Sopenharmony_ci return ret.dbl; 135425bb815Sopenharmony_ci} /* nextafter */ 136