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;
--- a/tests/test-fmodf.c
+++ b/tests/test-fmodf.c
@@ -30,6 +30,7 @@
 #define DOUBLE float
 #define L_(literal) literal##f
 #define MANT_DIG FLT_MANT_DIG
+#define MAX_EXP FLT_MAX_EXP
 #define FMOD fmodf
 #define RANDOM randomf
 #include "test-fmod.h"
--- a/tests/test-fmodl.c
+++ b/tests/test-fmodl.c
@@ -31,6 +31,7 @@
 #define DOUBLE long double
 #define L_(literal) literal##L
 #define MANT_DIG LDBL_MANT_DIG
+#define MAX_EXP LDBL_MAX_EXP
 #define FMOD fmodl
 #define RANDOM randoml
 #include "test-fmod.h"