diff options
| author | Lenard Mollenkopf <glibc@lenardmollenkopf.de> | 2025-04-08 14:16:54 +0200 |
|---|---|---|
| committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2025-04-08 12:51:51 +0000 |
| commit | 5b132ec2b7712dbc055838b3b538b83ad1196414 (patch) | |
| tree | 28355a9f14cbf15da68217aba5e3be48169092a2 | |
| parent | 4fa959d13d21b8f56a43aa0a416100303736c55c (diff) | |
| download | glibc-5b132ec2b7712dbc055838b3b538b83ad1196414.tar.xz glibc-5b132ec2b7712dbc055838b3b538b83ad1196414.zip | |
stdlib: Implement C2Y uabs, ulabs, ullabs and uimaxabs
C2Y adds unsigned versions of the abs functions (see C2Y draft N3467 and
proposal N3349).
Tested for x86_64.
Signed-off-by: Lenard Mollenkopf <glibc@lenardmollenkopf.de>
47 files changed, 475 insertions, 2 deletions
@@ -18,6 +18,9 @@ Major new features: * On Linux, the pthread_gettid_np function has been added. +* The ISO C2Y family of unsigned abs functions, i.e. + uabs, ulabs, ullabs and uimaxabs, are now supported. + Deprecated and removed features, and other changes affecting compatibility: [Add deprecations, removals and changes affecting compatibility here] diff --git a/manual/arith.texi b/manual/arith.texi index 034d9d2ba5..d500dcf2a9 100644 --- a/manual/arith.texi +++ b/manual/arith.texi @@ -1233,25 +1233,33 @@ whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt @pindex math.h @pindex stdlib.h -Prototypes for @code{abs}, @code{labs} and @code{llabs} are in @file{stdlib.h}; -@code{imaxabs} is declared in @file{inttypes.h}; +Prototypes for @code{abs}, @code{labs}, @code{llabs}, +@code{uabs}, @code{ulabs} and @code{ullabs} are in @file{stdlib.h}; +@code{imaxabs} and @code{uimaxabs} are declared in @file{inttypes.h}; the @code{fabs} functions are declared in @file{math.h}; the @code{cabs} functions are declared in @file{complex.h}. @deftypefun int abs (int @var{number}) @deftypefunx {long int} labs (long int @var{number}) @deftypefunx {long long int} llabs (long long int @var{number}) +@deftypefunx {unsigned int} uabs (int @var{number}) +@deftypefunx {unsigned long int} ulabs (long int @var{number}) +@deftypefunx {unsigned long long int} ullabs (long long int @var{number}) @deftypefunx intmax_t imaxabs (intmax_t @var{number}) +@deftypefunx uintmax_t uimaxabs (intmax_t @var{number}) @standards{ISO, stdlib.h} @standardsx{imaxabs, ISO, inttypes.h} +@standardsx{uimaxabs, ISO, inttypes.h} @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} These functions return the absolute value of @var{number}. Most computers use a two's complement integer representation, in which the absolute value of @code{INT_MIN} (the smallest possible @code{int}) cannot be represented; thus, @w{@code{abs (INT_MIN)}} is not defined. +Using @code{uabs} avoids this. @code{llabs} and @code{imaxdiv} are new to @w{ISO C99}. +@code{uabs}, @code{ulabs}, @code{ullabs} and @code{uimaxabs} are new to @w{ISO C2Y}. See @ref{Integers} for a description of the @code{intmax_t} type. diff --git a/stdlib/Makefile b/stdlib/Makefile index 513445bcbc..1c80e497f0 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -211,6 +211,9 @@ routines := \ strtoull_l \ swapcontext \ system \ + uabs \ + ulabs \ + ullabs \ wcstombs \ wctomb \ xpg_basename \ @@ -363,6 +366,10 @@ tests := \ tst-swapcontext2 \ tst-thread-quick_exit \ tst-tininess \ + tst-uabs \ + tst-uimaxabs \ + tst-ulabs \ + tst-ullabs \ tst-unsetenv1 \ tst-width \ tst-width-stdint \ @@ -412,6 +419,11 @@ CFLAGS-tst-abs.c += -fno-builtin CFLAGS-tst-labs.c += -fno-builtin CFLAGS-tst-llabs.c += -fno-builtin +CFLAGS-tst-uabs.c += -fno-builtin +CFLAGS-tst-uimaxabs.c += -fno-builtin +CFLAGS-tst-ulabs.c += -fno-builtin +CFLAGS-tst-ullabs.c += -fno-builtin + CFLAGS-tst-stdbit-Wconversion.c += -Wconversion -Werror CFLAGS-tst-stdc_trailing_zeros.c += -fno-builtin CFLAGS-tst-stdc_trailing_ones.c += -fno-builtin diff --git a/stdlib/Versions b/stdlib/Versions index ea2265bbd4..6d024000f8 100644 --- a/stdlib/Versions +++ b/stdlib/Versions @@ -223,6 +223,12 @@ libc { stdc_bit_ceil_ul; stdc_bit_ceil_ull; } + GLIBC_2.42 { + uabs; + uimaxabs; + ulabs; + ullabs; + } GLIBC_PRIVATE { # functions which have an additional interface since they are # are cancelable. diff --git a/stdlib/inttypes.h b/stdlib/inttypes.h index 95324f0784..9726abf5b1 100644 --- a/stdlib/inttypes.h +++ b/stdlib/inttypes.h @@ -350,6 +350,11 @@ typedef struct /* Compute absolute value of N. */ extern intmax_t imaxabs (intmax_t __n) __THROW __attribute__ ((__const__)); + +#if __GLIBC_USE (ISOC2Y) +extern uintmax_t uimaxabs (intmax_t __n) __THROW __attribute__ ((__const__)); +#endif + /* Return the `imaxdiv_t' representation of the value of NUMER over DENOM. */ extern imaxdiv_t imaxdiv (intmax_t __numer, intmax_t __denom) __THROW __attribute__ ((__const__)); diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index 975f5aeb0b..cd4503c761 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -985,6 +985,12 @@ __extension__ extern long long int llabs (long long int __x) __THROW __attribute__ ((__const__)) __wur; #endif +#if __GLIBC_USE (ISOC2Y) +extern unsigned int uabs (int __x) __THROW __attribute__ ((__const__)) __wur; +extern unsigned long int ulabs (long int __x) __THROW __attribute__ ((__const__)) __wur; +__extension__ extern unsigned long long int ullabs (long long int __x) + __THROW __attribute__ ((__const__)) __wur; +#endif /* Return the `div_t', `ldiv_t' or `lldiv_t' representation of the value of NUMER over DENOM. */ diff --git a/stdlib/tst-uabs.c b/stdlib/tst-uabs.c new file mode 100644 index 0000000000..13c9f58dc0 --- /dev/null +++ b/stdlib/tst-uabs.c @@ -0,0 +1,45 @@ +/* Basic tests for uabs. + Copyright (C) 2025 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 + <https://www.gnu.org/licenses/>. */ + +#include <limits.h> +#include <stdlib.h> + +#include <support/check.h> + +#define LARGE_PRIME 49999 + +static int do_test (void) +{ + int i; + + TEST_COMPARE (uabs (INT_MAX), INT_MAX); + TEST_COMPARE (uabs (INT_MIN), (unsigned int)INT_MAX + 1); + TEST_COMPARE (uabs (-1), 1); + TEST_COMPARE (uabs (0), 0); + TEST_COMPARE (uabs (1), 1); + + for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) + TEST_COMPARE (uabs (i), -i); + + for (i = 0; i < INT_MAX - LARGE_PRIME; i += LARGE_PRIME) + TEST_COMPARE (uabs (i), i); + + return EXIT_SUCCESS; +} + +#include <support/test-driver.c> diff --git a/stdlib/tst-uimaxabs.c b/stdlib/tst-uimaxabs.c new file mode 100644 index 0000000000..4500ec1797 --- /dev/null +++ b/stdlib/tst-uimaxabs.c @@ -0,0 +1,51 @@ +/* Basic tests for uimaxabs. + Copyright (C) 2025 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 + <https://www.gnu.org/licenses/>. */ + +#include <inttypes.h> +#include <limits.h> +#include <stdlib.h> + +#include <support/check.h> + +#define LARGE_PRIME 49999 + +static int do_test (void) +{ + intmax_t i; + + TEST_COMPARE (uimaxabs (INTMAX_MIN), (uintmax_t)INTMAX_MAX + 1); + TEST_COMPARE (uimaxabs (-1), 1); + TEST_COMPARE (uimaxabs (0), 0); + TEST_COMPARE (uimaxabs (1), 1); + + for (i = INTMAX_MIN + 1; i < INTMAX_MIN + INT_MAX; i += LARGE_PRIME) + TEST_COMPARE (uimaxabs (i), -i); + + for (i = INTMAX_MAX - INT_MAX; i < INTMAX_MAX - LARGE_PRIME; i += LARGE_PRIME) + TEST_COMPARE (uimaxabs (i), i); + + for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) + TEST_COMPARE (uimaxabs (i), -i); + + for (i = 0; i < INT_MAX; i += LARGE_PRIME) + TEST_COMPARE (uimaxabs (i), i); + + return EXIT_SUCCESS; +} + +#include <support/test-driver.c> diff --git a/stdlib/tst-ulabs.c b/stdlib/tst-ulabs.c new file mode 100644 index 0000000000..3b5323e051 --- /dev/null +++ b/stdlib/tst-ulabs.c @@ -0,0 +1,52 @@ +/* Basic tests for ulabs. + Copyright (C) 2025 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 + <https://www.gnu.org/licenses/>. */ + +#include <limits.h> +#include <stdlib.h> + +#include <support/check.h> + +#define LARGE_PRIME 49999 + +static int do_test (void) +{ + long int i; + + TEST_COMPARE (ulabs (LONG_MAX), LONG_MAX); + TEST_COMPARE (ulabs (LONG_MIN), (unsigned long int)LONG_MAX + 1); + TEST_COMPARE (ulabs (-1), 1); + TEST_COMPARE (ulabs (0), 0); + TEST_COMPARE (ulabs (1), 1); + + for (i = LONG_MIN + 1; i < LONG_MIN + INT_MAX; i += LARGE_PRIME) + TEST_COMPARE (ulabs (i), -i); + + for (i = LONG_MAX - INT_MAX; i < LONG_MAX - LARGE_PRIME; + i += LARGE_PRIME) + TEST_COMPARE (ulabs (i), i); + + for (i = INT_MIN + 1; i < 0; i += LARGE_PRIME) + TEST_COMPARE (ulabs (i), -i); + + for (i = 0; i <= INT_MAX - LARGE_PRIME; i += LARGE_PRIME) + TEST_COMPARE (ulabs (i), i); + + return EXIT_SUCCESS; +} + +#include <support/test-driver.c> diff --git a/stdlib/tst-ullabs.c b/stdlib/tst-ullabs.c new file mode 100644 index 0000000000..ac34ec776e --- /dev/null +++ b/stdlib/tst-ullabs.c @@ -0,0 +1,55 @@ +/* Basic tests for ullabs. + Copyright (C) 2025 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 GN |
