1570af302Sopenharmony_ci#include "libm.h" 2570af302Sopenharmony_ci 3570af302Sopenharmony_cifloat nextafterf(float x, float y) 4570af302Sopenharmony_ci{ 5570af302Sopenharmony_ci union {float f; uint32_t i;} ux={x}, uy={y}; 6570af302Sopenharmony_ci uint32_t ax, ay, e; 7570af302Sopenharmony_ci 8570af302Sopenharmony_ci if (isnan(x) || isnan(y)) 9570af302Sopenharmony_ci return x + y; 10570af302Sopenharmony_ci if (ux.i == uy.i) 11570af302Sopenharmony_ci return y; 12570af302Sopenharmony_ci ax = ux.i & 0x7fffffff; 13570af302Sopenharmony_ci ay = uy.i & 0x7fffffff; 14570af302Sopenharmony_ci if (ax == 0) { 15570af302Sopenharmony_ci if (ay == 0) 16570af302Sopenharmony_ci return y; 17570af302Sopenharmony_ci ux.i = (uy.i & 0x80000000) | 1; 18570af302Sopenharmony_ci } else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000)) 19570af302Sopenharmony_ci ux.i--; 20570af302Sopenharmony_ci else 21570af302Sopenharmony_ci ux.i++; 22570af302Sopenharmony_ci e = ux.i & 0x7f800000; 23570af302Sopenharmony_ci /* raise overflow if ux.f is infinite and x is finite */ 24570af302Sopenharmony_ci if (e == 0x7f800000) 25570af302Sopenharmony_ci FORCE_EVAL(x+x); 26570af302Sopenharmony_ci /* raise underflow if ux.f is subnormal or zero */ 27570af302Sopenharmony_ci if (e == 0) 28570af302Sopenharmony_ci FORCE_EVAL(x*x + ux.f*ux.f); 29570af302Sopenharmony_ci return ux.f; 30570af302Sopenharmony_ci} 31