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