doc: use ASCII in .texi files where UTF-8 isn't needed
[gnulib.git] / tests / test-ceilf2.c
index f5e886b..97f019d 100644 (file)
@@ -1,5 +1,5 @@
 /* Test of rounding towards positive infinity.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007-2014 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
@@ -16,6 +16,9 @@
 
 /* Written by Bruno Haible <bruno@clisp.org>, 2007.  */
 
+/* When this test fails on some platform, build it together with the gnulib
+   module 'fprintf-posix' for optimal debugging output.  */
+
 #include <config.h>
 
 #include <math.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
-#include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
+#include "minus-zero.h"
+#include "macros.h"
 
-#define ASSERT(expr) \
-  do                                                                        \
-    {                                                                       \
-      if (!(expr))                                                          \
-        {                                                                   \
-          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
-          abort ();                                                         \
-        }                                                                   \
-    }                                                                       \
-  while (0)
+/* MSVC with option -fp:strict refuses to compile constant initializers that
+   contain floating-point operations.  Pacify this compiler.  */
+#ifdef _MSC_VER
+# pragma fenv_access (off)
+#endif
 
 
 /* The reference implementation, taken from lib/ceil.c.  */
@@ -46,6 +45,9 @@
 #define MANT_DIG FLT_MANT_DIG
 #define L_(literal) literal##f
 
+/* -0.0.  See minus-zero.h.  */
+#define MINUS_ZERO minus_zerof
+
 /* 2^(MANT_DIG-1).  */
 static const DOUBLE TWO_MANT_DIG =
   /* Assume MANT_DIG <= 5 * 31.
@@ -71,29 +73,36 @@ ceilf_reference (DOUBLE x)
 
   if (z > L_(0.0))
     {
+      /* Work around ICC's desire to optimize denormal floats to 0.  */
+      if (z < FLT_MIN)
+        return L_(1.0);
       /* Avoid rounding errors for values near 2^k, where k >= MANT_DIG-1.  */
       if (z < TWO_MANT_DIG)
-       {
-         /* Round to the next integer (nearest or up or down, doesn't matter).  */
-         z += TWO_MANT_DIG;
-         z -= TWO_MANT_DIG;
-         /* Enforce rounding up.  */
-         if (z < y)
-           z += L_(1.0);
-       }
+        {
+          /* Round to the next integer (nearest or up or down, doesn't matter).  */
+          z += TWO_MANT_DIG;
+          z -= TWO_MANT_DIG;
+          /* Enforce rounding up.  */
+          if (z < y)
+            z += L_(1.0);
+        }
     }
   else if (z < L_(0.0))
     {
+      /* For -1 < x < 0, return -0.0 regardless of the current rounding
+         mode.  */
+      if (z > L_(-1.0))
+        z = MINUS_ZERO;
       /* Avoid rounding errors for values near -2^k, where k >= MANT_DIG-1.  */
-      if (z > - TWO_MANT_DIG)
-       {
-         /* Round to the next integer (nearest or up or down, doesn't matter).  */
-         z -= TWO_MANT_DIG;
-         z += TWO_MANT_DIG;
-         /* Enforce rounding up.  */
-         if (z < y)
-           z += L_(1.0);
-       }
+      else if (z > - TWO_MANT_DIG)
+        {
+          /* Round to the next integer (nearest or up or down, doesn't matter).  */
+          z -= TWO_MANT_DIG;
+          z += TWO_MANT_DIG;
+          /* Enforce rounding up.  */
+          if (z < y)
+            z += L_(1.0);
+        }
     }
   return z;
 }
@@ -130,9 +139,11 @@ check (float x)
       return 0;
     else
       {
-       fprintf (stderr, "ceilf %g(%a) = %g(%a) or %g(%a)?\n",
-                x, x, reference, reference, result, result);
-       return 1;
+#if GNULIB_TEST_FPRINTF_POSIX
+        fprintf (stderr, "ceilf %g(%a) = %g(%a) or %g(%a)?\n",
+                 x, x, reference, reference, result, result);
+#endif
+        return 1;
       }
   }
 }
@@ -149,14 +160,14 @@ main ()
   for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
     for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
       {
-       /* Combine highbits and lowbits into a floating-point number,
-          sign-extending the lowbits to 32-NUM_HIGHBITS bits.  */
-       union { float f; uint32_t i; } janus;
-       janus.i = ((uint32_t) highbits << (32 - NUM_HIGHBITS))
-                 | ((uint32_t) ((int32_t) ((uint32_t) lowbits << (32 - NUM_LOWBITS))
-                                >> (32 - NUM_LOWBITS - NUM_HIGHBITS))
-                    >> NUM_HIGHBITS);
-       error |= check (janus.f);
+        /* Combine highbits and lowbits into a floating-point number,
+           sign-extending the lowbits to 32-NUM_HIGHBITS bits.  */
+        union { float f; uint32_t i; } janus;
+        janus.i = ((uint32_t) highbits << (32 - NUM_HIGHBITS))
+                  | ((uint32_t) ((int32_t) ((uint32_t) lowbits << (32 - NUM_LOWBITS))
+                                 >> (32 - NUM_LOWBITS - NUM_HIGHBITS))
+                     >> NUM_HIGHBITS);
+        error |= check (janus.f);
       }
   return (error ? 1 : 0);
 }