#include <math.h>
#include <float.h>
#include "math_private.h"
double
nexttoward(double x, long double y)
{
int32_t hx,ix,iy;
u_int32_t lx,hy,ly,esy;
EXTRACT_WORDS(hx,lx,x);
GET_LDOUBLE_WORDS(esy,hy,ly,y);
ix = hx&0x7fffffff;
iy = esy&0x7fff;
if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||
((iy>=0x7fff)&&(hy|ly)!=0))
return x+y;
if((long double) x==y) return y;
if((ix|lx)==0) {
volatile double u;
INSERT_WORDS(x,(esy&0x8000)<<16,1);
u = x;
u = u * u;
return x;
}
if(hx>=0) {
if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) {
if(lx==0) hx -= 1;
lx -= 1;
} else {
lx += 1;
if(lx==0) hx += 1;
}
} else {
if (esy<0x8000||((ix>>20)&0x7ff)>iy-0x3c00
|| (((ix>>20)&0x7ff)==iy-0x3c00
&& (((hx<<11)|(lx>>21))>(hy&0x7fffffff)
|| (((hx<<11)|(lx>>21))==(hy&0x7fffffff)
&& (lx<<11)>ly)))) {
if(lx==0) hx -= 1;
lx -= 1;
} else {
lx += 1;
if(lx==0) hx += 1;
}
}
hy = hx&0x7ff00000;
if(hy>=0x7ff00000) {
x = x+x;
return x;
}
if(hy<0x00100000) {
volatile double u = x*x;
if(u==x) {
INSERT_WORDS(x,hx,lx);
return x;
}
}
INSERT_WORDS(x,hx,lx);
return x;
}