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