github.com/afumu/libc@v0.0.6/musl/src/math/nextafter.c (about)

     1  #include "libm.h"
     2  
     3  double nextafter(double x, double y)
     4  {
     5  	union {double f; uint64_t i;} ux={x}, uy={y};
     6  	uint64_t ax, ay;
     7  	int e;
     8  
     9  	if (isnan(x) || isnan(y))
    10  		return x + y;
    11  	if (ux.i == uy.i)
    12  		return y;
    13  	ax = ux.i & -1ULL/2;
    14  	ay = uy.i & -1ULL/2;
    15  	if (ax == 0) {
    16  		if (ay == 0)
    17  			return y;
    18  		ux.i = (uy.i & 1ULL<<63) | 1;
    19  	} else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
    20  		ux.i--;
    21  	else
    22  		ux.i++;
    23  	e = ux.i >> 52 & 0x7ff;
    24  	/* raise overflow if ux.f is infinite and x is finite */
    25  	if (e == 0x7ff)
    26  		FORCE_EVAL(x+x);
    27  	/* raise underflow if ux.f is subnormal or zero */
    28  	if (e == 0)
    29  		FORCE_EVAL(x*x + ux.f*ux.f);
    30  	return ux.f;
    31  }