#include "libm.h"

float nexttowardf(float x, long double y)
{
    union
    {
        float f;
        uint32_t i;
    } ux = {x};
    uint32_t e;

    if (isnan(x) || isnan(y))
        return x + y;
    if (x == y)
        return y;
    if (x == 0)
    {
        ux.i = 1;
        if (signbit(y))
            ux.i |= 0x80000000;
    }
    else if (x < y)
    {
        if (signbit(x))
            ux.i--;
        else
            ux.i++;
    }
    else
    {
        if (signbit(x))
            ux.i++;
        else
            ux.i--;
    }
    e = ux.i & 0x7f800000;
    /* raise overflow if ux.f is infinite and x is finite */
    if (e == 0x7f800000)
        FORCE_EVAL(x + x);
    /* raise underflow if ux.f is subnormal or zero */
    if (e == 0)
        FORCE_EVAL(x * x + ux.f * ux.f);
    return ux.f;
}
