diff options
author | Joseph Myers <joseph@codesourcery.com> | 2016-12-21 01:48:27 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2016-12-21 01:48:27 +0000 |
commit | 41c67149b94676347b0068a902058f130e3e88e6 (patch) | |
tree | b4f50fdb48fd83914ad570b581188b74ab90e984 /manual | |
parent | 60c07b058f9fe34e2ffd7e02b20657db6f5f68d4 (diff) | |
download | glibc-41c67149b94676347b0068a902058f130e3e88e6.tar.gz glibc-41c67149b94676347b0068a902058f130e3e88e6.tar.xz glibc-41c67149b94676347b0068a902058f130e3e88e6.zip |
Add roundeven, roundevenf, roundevenl.
TS 18661-1 defines roundeven functions that round a floating-point number to the nearest integer, in that floating-point type, with ties rounding to even (whereas the round functions round ties away from zero). As with other such functions, they raise no exceptions apart from "invalid" for signaling NaNs. There was a previous user request for this functionality in glibc in <https://sourceware.org/ml/libc-help/2015-02/msg00005.html>. This patch implements these functions for glibc. The implementations use integer bit-manipulation (or roundeven on the high and low parts, in the IBM long double case). It's possible that there may be faster approaches on some architectures (in particular, on AArch64 the frintn instruction should do exactly what's required); I'll leave it to architecture maintainers or others interested to implement such architecture-specific versions if desired. (Where architectures have instructions to round to nearest integer in the current rounding mode, implementations saving and restoring the rounding mode - and dealing with exceptions if those instructions generate "inexact" - are also possible, though their performance depends on the cost of manipulating exceptions / rounding mode state.) Tested for x86_64, x86, mips64 and powerpc. * math/bits/mathcalls.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (roundeven): New declaration. * math/tgmath.h [__GLIBC_USE (IEC_60559_BFP_EXT)] (roundeven): New macro. * math/Versions (roundeven): New libm symbol at version GLIBC_2.25. (roundevenf): Likewise. (roundevenl): Likewise. * math/Makefile (libm-calls): Add s_roundevenF. * math/libm-test.inc (roundeven_test_data): New array. (roundeven_test): New function. (main): Call roundeven_test. * math/test-tgmath.c (NCALLS): Increase to 134. (F(compile_test)): Call roundeven. (F(roundeven)): New function. * manual/arith.texi (Rounding Functions): Document roundeven, roundevenf and roundevenl. * manual/libm-err-tab.pl (@all_functions): Add roundeven. * include/math.h (roundeven): Use libm_hidden_proto. * sysdeps/ieee754/dbl-64/s_roundeven.c: New file. * sysdeps/ieee754/dbl-64/wordsize-64/s_roundeven.c: Likewise. * sysdeps/ieee754/flt-32/s_roundevenf.c: Likewise. * sysdeps/ieee754/ldbl-128/s_roundevenl.c: Likewise. * sysdeps/ieee754/ldbl-128ibm/s_roundevenl.c: Likewise. * sysdeps/ieee754/ldbl-96/s_roundevenl.c: Likewise. * sysdeps/ieee754/ldbl-opt/Makefile (libnldbl-calls): Add roundeven. (CFLAGS-nldbl-roundeven.c): New variable. * sysdeps/ieee754/ldbl-opt/nldbl-roundeven.c: New file. * sysdeps/nacl/libm.abilist: Update. * sysdeps/unix/sysv/linux/aarch64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/alpha/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/arm/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/hppa/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/i386/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/ia64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/coldfire/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/m68k/m680x0/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/microblaze/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/mips/mips64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/nios2/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm-le.abilist: Likewise. * sysdeps/unix/sysv/linux/powerpc/powerpc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sh/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx32/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilegx/tilegx64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/tile/tilepro/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/64/libm.abilist: Likewise. * sysdeps/unix/sysv/linux/x86_64/x32/libm.abilist: Likewise.
Diffstat (limited to 'manual')
-rw-r--r-- | manual/arith.texi | 14 | ||||
-rwxr-xr-x | manual/libm-err-tab.pl | 6 |
2 files changed, 17 insertions, 3 deletions
diff --git a/manual/arith.texi b/manual/arith.texi index f90ef26c91..b0464e101e 100644 --- a/manual/arith.texi +++ b/manual/arith.texi @@ -1596,6 +1596,20 @@ current rounding mode). @comment math.h @comment ISO +@deftypefun double roundeven (double @var{x}) +@comment math.h +@comment ISO +@deftypefunx float roundevenf (float @var{x}) +@comment math.h +@comment ISO +@deftypefunx {long double} roundevenl (long double @var{x}) +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +These functions, from TS 18661-1:2014, are similar to @code{round}, +but they round halfway cases to even instead of away from zero. +@end deftypefun + +@comment math.h +@comment ISO @deftypefun {long int} lrint (double @var{x}) @comment math.h @comment ISO diff --git a/manual/libm-err-tab.pl b/manual/libm-err-tab.pl index cc51f0b82f..9b8aa664ae 100755 --- a/manual/libm-err-tab.pl +++ b/manual/libm-err-tab.pl @@ -61,9 +61,9 @@ use vars qw (%results @all_floats %suffices @all_functions); "ilogb", "j0", "j1", "jn", "lgamma", "llogb", "lrint", "llrint", "log", "log10", "log1p", "log2", "logb", "lround", "llround", "modf", "nearbyint", "nextafter", "nextdown", "nexttoward", - "nextup", "pow", "remainder", "remquo", "rint", "round", "scalb", - "scalbn", "sin", "sincos", "sinh", "sqrt", "tan", "tanh", "tgamma", - "trunc", "y0", "y1", "yn" ); + "nextup", "pow", "remainder", "remquo", "rint", "round", "roundeven", + "scalb", "scalbn", "sin", "sincos", "sinh", "sqrt", "tan", "tanh", + "tgamma", "trunc", "y0", "y1", "yn" ); # canonicalize, fpclassify, getpayload, iscanonical, isnormal, # isfinite, isinf, isnan, issignaling, issubnormal, iszero, signbit, # iseqsig, isgreater, isgreaterequal, isless, islessequal, |