1*f504f610SAugustin Cavalier #include "libm.h" 2*f504f610SAugustin Cavalier nexttowardf(float x,long double y)3*f504f610SAugustin Cavalierfloat nexttowardf(float x, long double y) 4*f504f610SAugustin Cavalier { 5*f504f610SAugustin Cavalier union {float f; uint32_t i;} ux = {x}; 6*f504f610SAugustin Cavalier uint32_t e; 7*f504f610SAugustin Cavalier 8*f504f610SAugustin Cavalier if (isnan(x) || isnan(y)) 9*f504f610SAugustin Cavalier return x + y; 10*f504f610SAugustin Cavalier if (x == y) 11*f504f610SAugustin Cavalier return y; 12*f504f610SAugustin Cavalier if (x == 0) { 13*f504f610SAugustin Cavalier ux.i = 1; 14*f504f610SAugustin Cavalier if (signbit(y)) 15*f504f610SAugustin Cavalier ux.i |= 0x80000000; 16*f504f610SAugustin Cavalier } else if (x < y) { 17*f504f610SAugustin Cavalier if (signbit(x)) 18*f504f610SAugustin Cavalier ux.i--; 19*f504f610SAugustin Cavalier else 20*f504f610SAugustin Cavalier ux.i++; 21*f504f610SAugustin Cavalier } else { 22*f504f610SAugustin Cavalier if (signbit(x)) 23*f504f610SAugustin Cavalier ux.i++; 24*f504f610SAugustin Cavalier else 25*f504f610SAugustin Cavalier ux.i--; 26*f504f610SAugustin Cavalier } 27*f504f610SAugustin Cavalier e = ux.i & 0x7f800000; 28*f504f610SAugustin Cavalier /* raise overflow if ux.f is infinite and x is finite */ 29*f504f610SAugustin Cavalier if (e == 0x7f800000) 30*f504f610SAugustin Cavalier FORCE_EVAL(x+x); 31*f504f610SAugustin Cavalier /* raise underflow if ux.f is subnormal or zero */ 32*f504f610SAugustin Cavalier if (e == 0) 33*f504f610SAugustin Cavalier FORCE_EVAL(x*x + ux.f*ux.f); 34*f504f610SAugustin Cavalier return ux.f; 35*f504f610SAugustin Cavalier } 36