aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/ieee754')
-rw-r--r--sysdeps/ieee754/dbl-64/s_nextup.c58
-rw-r--r--sysdeps/ieee754/flt-32/s_nextupf.c46
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nextupl.c56
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nextupl.c78
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nextupl.c84
-rw-r--r--sysdeps/ieee754/ldbl-opt/Makefile5
-rw-r--r--sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c27
-rw-r--r--sysdeps/ieee754/ldbl-opt/nldbl-nextup.c27
8 files changed, 380 insertions, 1 deletions
diff --git a/sysdeps/ieee754/dbl-64/s_nextup.c b/sysdeps/ieee754/dbl-64/s_nextup.c
new file mode 100644
index 0000000000..d2432b550b
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/s_nextup.c
@@ -0,0 +1,58 @@
+/* Return the least floating-point number greater than X.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X. */
+double
+__nextup (double x)
+{
+ int32_t hx, ix;
+ u_int32_t lx;
+
+ EXTRACT_WORDS (hx, lx, x);
+ ix = hx & 0x7fffffff;
+
+ if (((ix >= 0x7ff00000) && ((ix - 0x7ff00000) | lx) != 0)) /* x is nan. */
+ return x + x;
+ if ((ix | lx) == 0)
+ return DBL_TRUE_MIN;
+ if (hx >= 0)
+ { /* x > 0. */
+ if (isinf (x))
+ return x;
+ lx += 1;
+ if (lx == 0)
+ hx += 1;
+ }
+ else
+ { /* x < 0. */
+ if (lx == 0)
+ hx -= 1;
+ lx -= 1;
+ }
+ INSERT_WORDS (x, hx, lx);
+ return x;
+}
+
+weak_alias (__nextup, nextup)
+#ifdef NO_LONG_DOUBLE
+strong_alias (__nextup, __nextupl)
+weak_alias (__nextup, nextupl)
+#endif
diff --git a/sysdeps/ieee754/flt-32/s_nextupf.c b/sysdeps/ieee754/flt-32/s_nextupf.c
new file mode 100644
index 0000000000..9f3398e02e
--- /dev/null
+++ b/sysdeps/ieee754/flt-32/s_nextupf.c
@@ -0,0 +1,46 @@
+/* Return the least floating-point number greater than X.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X. */
+float
+__nextupf (float x)
+{
+ int32_t hx, ix;
+
+ GET_FLOAT_WORD (hx, x);
+ ix = hx & 0x7fffffff;
+ if (ix == 0)
+ return FLT_TRUE_MIN;
+ if (ix > 0x7f800000) /* x is nan. */
+ return x + x;
+ if (hx >= 0)
+ { /* x > 0. */
+ if (isinf (x))
+ return x;
+ hx += 1;
+ }
+ else
+ hx -= 1;
+ SET_FLOAT_WORD (x, hx);
+ return x;
+}
+
+weak_alias (__nextupf, nextupf)
diff --git a/sysdeps/ieee754/ldbl-128/s_nextupl.c b/sysdeps/ieee754/ldbl-128/s_nextupl.c
new file mode 100644
index 0000000000..3ee47d8090
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/s_nextupl.c
@@ -0,0 +1,56 @@
+/* Return the least floating-point number greater than X.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X. */
+long double
+__nextupl (long double x)
+{
+ int64_t hx, ix;
+ u_int64_t lx;
+
+ GET_LDOUBLE_WORDS64 (hx, lx, x);
+ ix = hx & 0x7fffffffffffffffLL;
+
+ /* x is nan. */
+ if (((ix >= 0x7fff000000000000LL)
+ && ((ix - 0x7fff000000000000LL) | lx) != 0))
+ return x + x;
+ if ((ix | lx) == 0)
+ return LDBL_TRUE_MIN;
+ if (hx >= 0)
+ { /* x > 0. */
+ if (isinf (x))
+ return x;
+ lx++;
+ if (lx == 0)
+ hx++;
+ }
+ else
+ { /* x < 0. */
+ if (lx == 0)
+ hx--;
+ lx--;
+ }
+ SET_LDOUBLE_WORDS64 (x, hx, lx);
+ return x;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c
new file mode 100644
index 0000000000..2a4fae7e2e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nextupl.c
@@ -0,0 +1,78 @@
+/* Return the least floating-point number greater than X.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <math_private.h>
+#include <math_ldbl_opt.h>
+
+/* Return the least floating-point number greater than X. */
+long double
+__nextupl (long double x)
+{
+ int64_t hx, ihx, lx;
+ double xhi, xlo, yhi;
+
+ ldbl_unpack (x, &xhi, &xlo);
+ EXTRACT_WORDS64 (hx, xhi);
+ EXTRACT_WORDS64 (lx, xlo);
+ ihx = hx & 0x7fffffffffffffffLL;
+
+ if (ihx > 0x7ff0000000000000LL) /* x is nan. */
+ return x + x; /* Signal the nan. */
+ if (ihx == 0)
+ return LDBL_TRUE_MIN;
+
+ long double u;
+ if ((hx == 0x7fefffffffffffffLL) && (lx == 0x7c8ffffffffffffeLL))
+ return INFINITY;
+ if ((uint64_t) hx >= 0xfff0000000000000ULL)
+ {
+ u = -0x1.fffffffffffff7ffffffffffff8p+1023L;
+ return u;
+ }
+ if (ihx <= 0x0360000000000000LL)
+ { /* x <= LDBL_MIN. */
+ x += LDBL_TRUE_MIN;
+ if (x == 0.0L) /* Handle negative LDBL_TRUE_MIN case. */
+ x = -0.0L;
+ return x;
+ }
+ /* If the high double is an exact power of two and the low
+ double is the opposite sign, then 1ulp is one less than
+ what we might determine from the high double. Similarly
+ if X is an exact power of two, and negative, because
+ making it a little larger will result in the exponent
+ decreasing by one and normalisation of the mantissa. */
+ if ((hx & 0x000fffffffffffffLL) == 0
+ && ((lx != 0 && lx != 0x8000000000000000LL && (hx ^ lx) < 0)
+ || ((lx == 0 || lx == 0x8000000000000000LL) && hx < 0)))
+ ihx -= 1LL << 52;
+ if (ihx < (106LL << 52))
+ { /* ulp will denormal. */
+ INSERT_WORDS64 (yhi, ihx & (0x7ffLL << 52));
+ u = yhi * 0x1p-105;
+ }
+ else
+ {
+ INSERT_WORDS64 (yhi, (ihx & (0x7ffLL << 52)) - (105LL << 52));
+ u = yhi;
+ }
+ return x + u;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-96/s_nextupl.c b/sysdeps/ieee754/ldbl-96/s_nextupl.c
new file mode 100644
index 0000000000..701842d3e1
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/s_nextupl.c
@@ -0,0 +1,84 @@
+/* Return the least floating-point number greater than X.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <math.h>
+#include <math_private.h>
+
+/* Return the least floating-point number greater than X. */
+long double
+__nextupl (long double x)
+{
+ u_int32_t hx, ix;
+ u_int32_t lx;
+ int32_t esx;
+
+ GET_LDOUBLE_WORDS (esx, hx, lx, x);
+ ix = esx & 0x7fff;
+
+ if (((ix == 0x7fff) && (((hx & 0x7fffffff) | lx) != 0))) /* x is nan. */
+ return x + x;
+ if ((ix | hx | lx) == 0)
+ return LDBL_TRUE_MIN;
+ if (esx >= 0)
+ { /* x > 0. */
+ if (isinf (x))
+ return x;
+ lx += 1;
+ if (lx == 0)
+ {
+ hx += 1;
+#if LDBL_MIN_EXP == -16381
+ if (hx == 0 || (esx == 0 && hx == 0x80000000))
+#else
+ if (hx == 0)
+#endif
+ {
+ esx += 1;
+ hx |= 0x80000000;
+ }
+ }
+ }
+ else
+ { /* x < 0. */
+ if (lx == 0)
+ {
+#if LDBL_MIN_EXP == -16381
+ if (hx <= 0x80000000 && esx != 0xffff8000)
+ {
+ esx -= 1;
+ hx = hx - 1;
+ if ((esx & 0x7fff) > 0)
+ hx |= 0x80000000;
+ }
+ else
+ hx -= 1;
+#else
+ if (ix != 0 && hx == 0x80000000)
+ hx = 0;
+ if (hx == 0)
+ esx -= 1;
+ hx -= 1;
+#endif
+ }
+ lx -= 1;
+ }
+ SET_LDOUBLE_WORDS (x, esx, hx, lx);
+ return x;
+}
+
+weak_alias (__nextupl, nextupl)
diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile
index 53091e410c..af08209570 100644
--- a/sysdeps/ieee754/ldbl-opt/Makefile
+++ b/sysdeps/ieee754/ldbl-opt/Makefile
@@ -40,7 +40,8 @@ libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \
isoc99_scanf isoc99_fscanf isoc99_sscanf \
isoc99_vscanf isoc99_vfscanf isoc99_vsscanf \
isoc99_wscanf isoc99_fwscanf isoc99_swscanf \
- isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf
+ isoc99_vwscanf isoc99_vfwscanf isoc99_vswscanf \
+ nextup nextdown
libnldbl-routines = $(libnldbl-calls:%=nldbl-%)
libnldbl-inhibit-o = $(object-suffixes)
libnldbl-static-only-routines = $(libnldbl-routines)
@@ -120,8 +121,10 @@ CFLAGS-nldbl-modf.c = -fno-builtin-modfl
CFLAGS-nldbl-nan.c = -fno-builtin-nanl
CFLAGS-nldbl-nearbyint.c = -fno-builtin-nearbyintl
CFLAGS-nldbl-nextafter.c = -fno-builtin-nextafterl
+CFLAGS-nldbl-nextdown.c = -fno-builtin-nextdownl
CFLAGS-nldbl-nexttoward.c = -fno-builtin-nexttoward -fno-builtin-nexttowardl
CFLAGS-nldbl-nexttowardf.c = -fno-builtin-nexttowardf
+CFLAGS-nldbl-nextup.c = -fno-builtin-nextupl
CFLAGS-nldbl-pow.c = -fno-builtin-powl
CFLAGS-nldbl-pow10.c = -fno-builtin-pow10l
CFLAGS-nldbl-remainder.c = -fno-builtin-remainderl -fno-builtin-dreml
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c b/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c
new file mode 100644
index 0000000000..3b0047c09d
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-nextdown.c
@@ -0,0 +1,27 @@
+/* Compatibility routine for IEEE double as long double for nextdown.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "nldbl-compat.h"
+
+/* Return the greatest floating-point number less than X. */
+double
+attribute_hidden
+nextdownl (double x)
+{
+ return nextdown (x);
+}
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c b/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c
new file mode 100644
index 0000000000..b557edffe3
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-nextup.c
@@ -0,0 +1,27 @@
+/* Compatibility routine for IEEE double as long double for nextup.
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "nldbl-compat.h"
+
+/* Return the least floating-point number greater than X. */
+double
+attribute_hidden
+nextupl (double x)
+{
+ return nextup (x);
+}