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