Mercurial > hg > octave-lojdl > gnulib-hg
changeset 16566:bd4785c10d56
fmod* tests: More tests.
* tests/test-fmod.h (my_ldexp): New function.
(test_function): Reduce amount of random numbers to test. Add tests
of very large quotients x / y.
* tests/test-fmod.c (MAX_EXP): New macro.
* tests/test-fmodf.c (MAX_EXP): Likewise.
* tests/test-fmodl.c (MAX_EXP): Likewise.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 04 Mar 2012 20:59:05 +0100 |
parents | 0badbd4d62e4 |
children | 05507ae4f78f |
files | ChangeLog tests/test-fmod.c tests/test-fmod.h tests/test-fmodf.c tests/test-fmodl.c |
diffstat | 5 files changed, 46 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2012-03-04 Bruno Haible <bruno@clisp.org> + + fmod* tests: More tests. + * tests/test-fmod.h (my_ldexp): New function. + (test_function): Reduce amount of random numbers to test. Add tests + of very large quotients x / y. + * tests/test-fmod.c (MAX_EXP): New macro. + * tests/test-fmodf.c (MAX_EXP): Likewise. + * tests/test-fmodl.c (MAX_EXP): Likewise. + 2012-03-04 Bruno Haible <bruno@clisp.org> fmod, fmodl: Fix computation for large quotients x / y.
--- a/tests/test-fmod.c +++ b/tests/test-fmod.c @@ -30,6 +30,7 @@ #define DOUBLE double #define L_(literal) literal #define MANT_DIG DBL_MANT_DIG +#define MAX_EXP DBL_MAX_EXP #define FMOD fmod #define RANDOM randomd #include "test-fmod.h"
--- a/tests/test-fmod.h +++ b/tests/test-fmod.h @@ -14,6 +14,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +static DOUBLE +my_ldexp (DOUBLE x, int d) +{ + for (; d > 0; d--) + x *= L_(2.0); + for (; d < 0; d++) + x *= L_(0.5); + return x; +} + static void test_function (void) { @@ -30,8 +40,8 @@ * (DOUBLE) (1U << ((MANT_DIG - 1 + 4) / 5)); /* Randomized tests. */ - for (i = 0; i < SIZEOF (RANDOM); i++) - for (j = 0; j < SIZEOF (RANDOM); j++) + for (i = 0; i < SIZEOF (RANDOM) / 5; i++) + for (j = 0; j < SIZEOF (RANDOM) / 5; j++) { DOUBLE x = L_(16.0) * RANDOM[i]; /* 0.0 <= x <= 16.0 */ DOUBLE y = RANDOM[j]; /* 0.0 <= y < 1.0 */ @@ -53,8 +63,8 @@ } } - for (i = 0; i < SIZEOF (RANDOM); i++) - for (j = 0; j < SIZEOF (RANDOM); j++) + for (i = 0; i < SIZEOF (RANDOM) / 5; i++) + for (j = 0; j < SIZEOF (RANDOM) / 5; j++) { DOUBLE x = L_(1.0e9) * RANDOM[i]; /* 0.0 <= x <= 10^9 */ DOUBLE y = RANDOM[j]; /* 0.0 <= y < 1.0 */ @@ -87,6 +97,25 @@ && z < - y + L_(2.0) * L_(1.0e9) / TWO_MANT_DIG)); } } + + { + int large_exp = (MAX_EXP - 1 < 1000 ? MAX_EXP - 1 : 1000); + DOUBLE large = my_ldexp (L_(1.0), large_exp); /* = 2^large_exp */ + for (i = 0; i < SIZEOF (RANDOM) / 10; i++) + for (j = 0; j < SIZEOF (RANDOM) / 10; j++) + { + DOUBLE x = large * RANDOM[i]; /* 0.0 <= x <= 2^large_exp */ + DOUBLE y = RANDOM[j]; /* 0.0 <= y < 1.0 */ + if (y > L_(0.0)) + { + DOUBLE z = FMOD (x, y); + /* Regardless how large the rounding errors are, the result + must be >= 0, < y. */ + ASSERT (z >= L_(0.0)); + ASSERT (z < y); + } + } + } } volatile DOUBLE x;