summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/math/nextafterl.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 13:54:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 13:54:38 +0000
commit8c1ab65c0f548d20b7f177bdb736daaf603340e1 (patch)
treedf55b7e75bf43f2bf500845b105afe3ac3a5157e /libc-top-half/musl/src/math/nextafterl.c
parentInitial commit. (diff)
downloadwasi-libc-upstream/0.0_git20221206.8b7148f.tar.xz
wasi-libc-upstream/0.0_git20221206.8b7148f.zip
Adding upstream version 0.0~git20221206.8b7148f.upstream/0.0_git20221206.8b7148f
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libc-top-half/musl/src/math/nextafterl.c')
-rw-r--r--libc-top-half/musl/src/math/nextafterl.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/math/nextafterl.c b/libc-top-half/musl/src/math/nextafterl.c
new file mode 100644
index 0000000..37e858f
--- /dev/null
+++ b/libc-top-half/musl/src/math/nextafterl.c
@@ -0,0 +1,75 @@
+#include "libm.h"
+
+#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
+long double nextafterl(long double x, long double y)
+{
+ return nextafter(x, y);
+}
+#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+ union ldshape ux, uy;
+
+ if (isnan(x) || isnan(y))
+ return x + y;
+ if (x == y)
+ return y;
+ ux.f = x;
+ if (x == 0) {
+ uy.f = y;
+ ux.i.m = 1;
+ ux.i.se = uy.i.se & 0x8000;
+ } else if ((x < y) == !(ux.i.se & 0x8000)) {
+ ux.i.m++;
+ if (ux.i.m << 1 == 0) {
+ ux.i.m = 1ULL << 63;
+ ux.i.se++;
+ }
+ } else {
+ if (ux.i.m << 1 == 0) {
+ ux.i.se--;
+ if (ux.i.se)
+ ux.i.m = 0;
+ }
+ ux.i.m--;
+ }
+ /* raise overflow if ux is infinite and x is finite */
+ if ((ux.i.se & 0x7fff) == 0x7fff)
+ return x + x;
+ /* raise underflow if ux is subnormal or zero */
+ if ((ux.i.se & 0x7fff) == 0)
+ FORCE_EVAL(x*x + ux.f*ux.f);
+ return ux.f;
+}
+#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
+long double nextafterl(long double x, long double y)
+{
+ union ldshape ux, uy;
+
+ if (isnan(x) || isnan(y))
+ return x + y;
+ if (x == y)
+ return y;
+ ux.f = x;
+ if (x == 0) {
+ uy.f = y;
+ ux.i.lo = 1;
+ ux.i.se = uy.i.se & 0x8000;
+ } else if ((x < y) == !(ux.i.se & 0x8000)) {
+ ux.i2.lo++;
+ if (ux.i2.lo == 0)
+ ux.i2.hi++;
+ } else {
+ if (ux.i2.lo == 0)
+ ux.i2.hi--;
+ ux.i2.lo--;
+ }
+ /* raise overflow if ux is infinite and x is finite */
+ if ((ux.i.se & 0x7fff) == 0x7fff)
+ return x + x;
+ /* raise underflow if ux is subnormal or zero */
+ if ((ux.i.se & 0x7fff) == 0)
+ FORCE_EVAL(x*x + ux.f*ux.f);
+ return ux.f;
+}
+#endif