1570af302Sopenharmony_ci#include "libm.h" 2570af302Sopenharmony_ci 3570af302Sopenharmony_ci#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 4570af302Sopenharmony_cilong double nextafterl(long double x, long double y) 5570af302Sopenharmony_ci{ 6570af302Sopenharmony_ci return nextafter(x, y); 7570af302Sopenharmony_ci} 8570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 9570af302Sopenharmony_cilong double nextafterl(long double x, long double y) 10570af302Sopenharmony_ci{ 11570af302Sopenharmony_ci union ldshape ux, uy; 12570af302Sopenharmony_ci 13570af302Sopenharmony_ci if (isnan(x) || isnan(y)) 14570af302Sopenharmony_ci return x + y; 15570af302Sopenharmony_ci if (x == y) 16570af302Sopenharmony_ci return y; 17570af302Sopenharmony_ci ux.f = x; 18570af302Sopenharmony_ci if (x == 0) { 19570af302Sopenharmony_ci uy.f = y; 20570af302Sopenharmony_ci ux.i.m = 1; 21570af302Sopenharmony_ci ux.i.se = uy.i.se & 0x8000; 22570af302Sopenharmony_ci } else if ((x < y) == !(ux.i.se & 0x8000)) { 23570af302Sopenharmony_ci ux.i.m++; 24570af302Sopenharmony_ci if (ux.i.m << 1 == 0) { 25570af302Sopenharmony_ci ux.i.m = 1ULL << 63; 26570af302Sopenharmony_ci ux.i.se++; 27570af302Sopenharmony_ci } 28570af302Sopenharmony_ci } else { 29570af302Sopenharmony_ci if (ux.i.m << 1 == 0) { 30570af302Sopenharmony_ci ux.i.se--; 31570af302Sopenharmony_ci if (ux.i.se) 32570af302Sopenharmony_ci ux.i.m = 0; 33570af302Sopenharmony_ci } 34570af302Sopenharmony_ci ux.i.m--; 35570af302Sopenharmony_ci } 36570af302Sopenharmony_ci /* raise overflow if ux is infinite and x is finite */ 37570af302Sopenharmony_ci if ((ux.i.se & 0x7fff) == 0x7fff) 38570af302Sopenharmony_ci return x + x; 39570af302Sopenharmony_ci /* raise underflow if ux is subnormal or zero */ 40570af302Sopenharmony_ci if ((ux.i.se & 0x7fff) == 0) 41570af302Sopenharmony_ci FORCE_EVAL(x*x + ux.f*ux.f); 42570af302Sopenharmony_ci return ux.f; 43570af302Sopenharmony_ci} 44570af302Sopenharmony_ci#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 45570af302Sopenharmony_cilong double nextafterl(long double x, long double y) 46570af302Sopenharmony_ci{ 47570af302Sopenharmony_ci union ldshape ux, uy; 48570af302Sopenharmony_ci 49570af302Sopenharmony_ci if (isnan(x) || isnan(y)) 50570af302Sopenharmony_ci return x + y; 51570af302Sopenharmony_ci if (x == y) 52570af302Sopenharmony_ci return y; 53570af302Sopenharmony_ci ux.f = x; 54570af302Sopenharmony_ci if (x == 0) { 55570af302Sopenharmony_ci uy.f = y; 56570af302Sopenharmony_ci ux.i.lo = 1; 57570af302Sopenharmony_ci ux.i.se = uy.i.se & 0x8000; 58570af302Sopenharmony_ci } else if ((x < y) == !(ux.i.se & 0x8000)) { 59570af302Sopenharmony_ci ux.i2.lo++; 60570af302Sopenharmony_ci if (ux.i2.lo == 0) 61570af302Sopenharmony_ci ux.i2.hi++; 62570af302Sopenharmony_ci } else { 63570af302Sopenharmony_ci if (ux.i2.lo == 0) 64570af302Sopenharmony_ci ux.i2.hi--; 65570af302Sopenharmony_ci ux.i2.lo--; 66570af302Sopenharmony_ci } 67570af302Sopenharmony_ci /* raise overflow if ux is infinite and x is finite */ 68570af302Sopenharmony_ci if ((ux.i.se & 0x7fff) == 0x7fff) 69570af302Sopenharmony_ci return x + x; 70570af302Sopenharmony_ci /* raise underflow if ux is subnormal or zero */ 71570af302Sopenharmony_ci if ((ux.i.se & 0x7fff) == 0) 72570af302Sopenharmony_ci FORCE_EVAL(x*x + ux.f*ux.f); 73570af302Sopenharmony_ci return ux.f; 74570af302Sopenharmony_ci} 75570af302Sopenharmony_ci#endif 76