1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double nextafterl(long double x, long double y)
5{
6	return nextafter(x, y);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double nextafterl(long double x, long double y)
10{
11	union ldshape ux, uy;
12
13	if (isnan(x) || isnan(y))
14		return x + y;
15	if (x == y)
16		return y;
17	ux.f = x;
18	if (x == 0) {
19		uy.f = y;
20		ux.i.m = 1;
21		ux.i.se = uy.i.se & 0x8000;
22	} else if ((x < y) == !(ux.i.se & 0x8000)) {
23		ux.i.m++;
24		if (ux.i.m << 1 == 0) {
25			ux.i.m = 1ULL << 63;
26			ux.i.se++;
27		}
28	} else {
29		if (ux.i.m << 1 == 0) {
30			ux.i.se--;
31			if (ux.i.se)
32				ux.i.m = 0;
33		}
34		ux.i.m--;
35	}
36	/* raise overflow if ux is infinite and x is finite */
37	if ((ux.i.se & 0x7fff) == 0x7fff)
38		return x + x;
39	/* raise underflow if ux is subnormal or zero */
40	if ((ux.i.se & 0x7fff) == 0)
41		FORCE_EVAL(x*x + ux.f*ux.f);
42	return ux.f;
43}
44#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
45long double nextafterl(long double x, long double y)
46{
47	union ldshape ux, uy;
48
49	if (isnan(x) || isnan(y))
50		return x + y;
51	if (x == y)
52		return y;
53	ux.f = x;
54	if (x == 0) {
55		uy.f = y;
56		ux.i.lo = 1;
57		ux.i.se = uy.i.se & 0x8000;
58	} else if ((x < y) == !(ux.i.se & 0x8000)) {
59		ux.i2.lo++;
60		if (ux.i2.lo == 0)
61			ux.i2.hi++;
62	} else {
63		if (ux.i2.lo == 0)
64			ux.i2.hi--;
65		ux.i2.lo--;
66	}
67	/* raise overflow if ux is infinite and x is finite */
68	if ((ux.i.se & 0x7fff) == 0x7fff)
69		return x + x;
70	/* raise underflow if ux is subnormal or zero */
71	if ((ux.i.se & 0x7fff) == 0)
72		FORCE_EVAL(x*x + ux.f*ux.f);
73	return ux.f;
74}
75#endif
76