From 72bd753df75b9e71a93e8403e56a958bd2ba0473 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 27 Oct 2023 20:26:56 +0200 Subject: [PATCH] fenv-rounding: Add tests. * tests/test-fenv-round.c: New file. * modules/fenv-rounding-tests: New file. --- ChangeLog | 4 + modules/fenv-rounding-tests | 12 +++ tests/test-fenv-round.c | 197 ++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 modules/fenv-rounding-tests create mode 100644 tests/test-fenv-round.c diff --git a/ChangeLog b/ChangeLog index b4c109b02a..2eb57b8d9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2023-10-27 Bruno Haible + fenv-rounding: Add tests. + * tests/test-fenv-round.c: New file. + * modules/fenv-rounding-tests: New file. + fenv-rounding: New module. * lib/fenv.in.h (fegetround, fesetround): New declarations. * lib/fenv-private.h: New file, based on glibc. diff --git a/modules/fenv-rounding-tests b/modules/fenv-rounding-tests new file mode 100644 index 0000000000..fc594933de --- /dev/null +++ b/modules/fenv-rounding-tests @@ -0,0 +1,12 @@ +Files: +tests/test-fenv-round.c +tests/macros.h + +Depends-on: + +configure.ac: + +Makefile.am: +TESTS += test-fenv-round +check_PROGRAMS += test-fenv-round +test_fenv_round_LDADD = $(LDADD) @FENV_ROUNDING_LIBM@ diff --git a/tests/test-fenv-round.c b/tests/test-fenv-round.c new file mode 100644 index 0000000000..aba783cc79 --- /dev/null +++ b/tests/test-fenv-round.c @@ -0,0 +1,197 @@ +/* Test of floating-point rounding direction. + Copyright (C) 2023 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2023. */ + +#include + +/* Specification. */ +#include + +#include "macros.h" + +/* Check the FE_TOWARDZERO rounding direction. */ +_GL_UNUSED static void +test_towardzero () +{ + { + float volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } + { + double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } +#if !(defined __FreeBSD__ && defined __aarch64__) + { + long double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } +#endif +} + +/* Check the FE_UPWARD rounding direction. */ +_GL_UNUSED static void +test_upward () +{ + { + float volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } + { + double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } +#if !(defined __FreeBSD__ && defined __aarch64__) + { + long double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p > a); + } +#endif +} + +/* Check the FE_DOWNWARD rounding direction. */ +_GL_UNUSED static void +test_downward () +{ + { + float volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + } + { + double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + } +#if !(defined __FreeBSD__ && defined __aarch64__) + { + long double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p < a); + } +#endif +} + +/* Check the FE_TONEAREST rounding direction. */ +static void +test_tonearest () +{ + { + float volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + } + { + double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + } + { + long double volatile a, b, q, p; + + a = 1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + + a = -1; b = 3; q = a / b; p = b * q; + ASSERT (p == a); + } +} + +int +main () +{ + /* Check that the default rounding direction is FE_TONEAREST. */ + test_tonearest (); + +/* On alpha, this test works only when compiled with the GCC option + '-mfp-rounding-mode=d'. */ +#if !((defined __arm__ && defined __SOFTFP__) || defined __alpha) +# if defined FE_TOWARDZERO + ASSERT (fesetround (FE_TOWARDZERO) == 0); + test_towardzero (); + ASSERT (fegetround () == FE_TOWARDZERO); +# endif + +# if defined FE_UPWARD + ASSERT (fesetround (FE_UPWARD) == 0); + test_upward (); + ASSERT (fegetround () == FE_UPWARD); +# endif + +# if defined FE_DOWNWARD + ASSERT (fesetround (FE_DOWNWARD) == 0); + test_downward (); + ASSERT (fegetround () == FE_DOWNWARD); +# endif +#endif + + ASSERT (fesetround (FE_TONEAREST) == 0); + test_tonearest (); + ASSERT (fegetround () == FE_TONEAREST); + + return 0; +} -- 2.39.5