blob: 827ee5c3c23ab0d9c33ff4205835bf068f0320e8 [file] [log] [blame]
Rich Felkerb69f6952012-03-13 01:17:53 -04001#include "libm.h"
nsz9560b6b2012-03-13 19:51:14 +01002
Rich Felkerb69f6952012-03-13 01:17:53 -04003#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4double nexttoward(double x, long double y)
5{
6 return nextafter(x, y);
7}
nsz6cf865d2012-05-06 13:08:59 +02008#else
Rich Felkerb69f6952012-03-13 01:17:53 -04009double nexttoward(double x, long double y)
10{
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000011 union {double f; uint64_t i;} ux = {x};
nsz6cf865d2012-05-06 13:08:59 +020012 int e;
Rich Felkerb69f6952012-03-13 01:17:53 -040013
nsz6cf865d2012-05-06 13:08:59 +020014 if (isnan(x) || isnan(y))
15 return x + y;
Rich Felkerb69f6952012-03-13 01:17:53 -040016 if (x == y)
nsz6cf865d2012-05-06 13:08:59 +020017 return y;
nsz6cf865d2012-05-06 13:08:59 +020018 if (x == 0) {
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000019 ux.i = 1;
nsz6cf865d2012-05-06 13:08:59 +020020 if (signbit(y))
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000021 ux.i |= 1ULL<<63;
nsz6cf865d2012-05-06 13:08:59 +020022 } else if (x < y) {
23 if (signbit(x))
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000024 ux.i--;
nsz6cf865d2012-05-06 13:08:59 +020025 else
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000026 ux.i++;
nsz6cf865d2012-05-06 13:08:59 +020027 } else {
28 if (signbit(x))
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000029 ux.i++;
nsz6cf865d2012-05-06 13:08:59 +020030 else
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000031 ux.i--;
Rich Felkerb69f6952012-03-13 01:17:53 -040032 }
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000033 e = ux.i>>52 & 0x7ff;
34 /* raise overflow if ux.f is infinite and x is finite */
nsz6cf865d2012-05-06 13:08:59 +020035 if (e == 0x7ff)
Szabolcs Nagy662ed202012-11-13 10:12:07 +010036 FORCE_EVAL(x+x);
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000037 /* raise underflow if ux.f is subnormal or zero */
nsz6ab81362012-05-06 21:24:28 +020038 if (e == 0)
Szabolcs Nagy8dba5482013-09-04 17:36:00 +000039 FORCE_EVAL(x*x + ux.f*ux.f);
40 return ux.f;
Rich Felkerb69f6952012-03-13 01:17:53 -040041}
42#endif