root/maint/gnulib/tests/test-round2.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. equal
  2. check
  3. main

   1 /* Test of rounding to nearest, breaking ties away from zero.
   2    Copyright (C) 2007-2021 Free Software Foundation, Inc.
   3 
   4    This program is free software: you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 3 of the License, or
   7    (at your option) any later version.
   8 
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13 
  14    You should have received a copy of the GNU General Public License
  15    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  16 
  17 /* Written by Ben Pfaff <blp@gnu.org>, 2007.
  18    Heavily based on code by Bruno Haible. */
  19 
  20 /* When this test fails on some platform, build it together with the gnulib
  21    module 'fprintf-posix' for optimal debugging output.  */
  22 
  23 /* Get the two reference implementations of round under the names
  24    round_reference1 and round_reference2.
  25 
  26    round.c will #include <config.h> for us. */
  27 #define FLOOR_BASED_ROUND round_reference1
  28 #define FLOOR_FREE_ROUND round_reference2
  29 #include "round.c"
  30 
  31 #include <math.h>
  32 #include <float.h>
  33 #include <stdbool.h>
  34 #include <stdint.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 
  38 #include "verify.h"
  39 
  40 #ifdef USE_LONG_DOUBLE
  41 # error Long double not supported.
  42 #elif ! defined USE_FLOAT
  43 # include "isnand-nolibm.h"
  44 # define ISNAN isnand
  45 # define FUNCTION "round"
  46 # define DOUBLE_UINT uint64_t
  47 # define DOUBLE_BITS 64
  48 # define NUM_HIGHBITS 13
  49 # define NUM_LOWBITS 4
  50 #else /* defined USE_FLOAT */
  51 # include "isnanf-nolibm.h"
  52 # define ISNAN isnanf
  53 # define FUNCTION "roundf"
  54 # define DOUBLE_UINT uint32_t
  55 # define DOUBLE_BITS 32
  56 # define NUM_HIGHBITS 12
  57 # define NUM_LOWBITS 4
  58 #endif
  59 
  60 /* Test for equality.  */
  61 static bool
  62 equal (const char *message, DOUBLE x, DOUBLE y0, DOUBLE y1)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64   if (ISNAN (y0) ? ISNAN (y1) : y0 == y1)
  65     return true;
  66   else
  67     {
  68 #if GNULIB_TEST_FPRINTF_POSIX
  69       fprintf (stderr, "%s: "FUNCTION"(%g(%a)) = %g(%a) or %g(%a)?\n",
  70                message, x, x, y0, y0, y1, y1);
  71 #endif
  72       return false;
  73     }
  74 }
  75 
  76 /* Test the function for a given argument.  */
  77 static bool
  78 check (DOUBLE x)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80   DOUBLE ref1 = round_reference1 (x);
  81   DOUBLE ref2 = round_reference2 (x);
  82   DOUBLE result = ROUND (x);
  83 
  84   /* If the reference implementations disagree, bail out immediately.  */
  85   if (!equal ("reference implementations disagree", x, ref1, ref2))
  86     exit (EXIT_FAILURE);
  87 
  88   /* If the actual implementation is wrong, return an error code.  */
  89   return equal ("bad round implementation", x, ref1, result);
  90 }
  91 
  92 int
  93 main (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95   DOUBLE_UINT highbits, lowbits;
  96   int error = 0;
  97   for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
  98     for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
  99       {
 100         /* Combine highbits and lowbits into a floating-point number,
 101            sign-extending the lowbits to DOUBLE_BITS-NUM_HIGHBITS bits.  */
 102         union { DOUBLE f; DOUBLE_UINT i; } janus;
 103         verify (sizeof janus.f == sizeof janus.i);
 104         janus.i = lowbits | (highbits << (DOUBLE_BITS - NUM_HIGHBITS));
 105         if (lowbits >> (NUM_LOWBITS - 1))
 106           janus.i |= ((DOUBLE_UINT) -1
 107                       >> (NUM_LOWBITS + NUM_HIGHBITS)
 108                       << NUM_LOWBITS);
 109         if (!check (janus.f))
 110           error = true;
 111       }
 112   return (error ? 1 : 0);
 113 }

/* [previous][next][first][last][top][bottom][index][help] */