usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-round2.c
blobfa3890e566ab0ba000f82b1e8a79fe5f17ccb81d
1 /* Test of rounding to nearest, breaking ties away from zero.
2 Copyright (C) 2007-2024 Free Software Foundation, Inc.
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.
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.
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/>. */
17 /* Written by Ben Pfaff <blp@gnu.org>, 2007.
18 Heavily based on code by Bruno Haible. */
20 /* When this test fails on some platform, build it together with the gnulib
21 module 'fprintf-posix' for optimal debugging output. */
23 /* Get the two reference implementations of round under the names
24 round_reference1 and round_reference2.
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"
31 #include <math.h>
32 #include <float.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
37 #ifdef USE_LONG_DOUBLE
38 # error Long double not supported.
39 #elif ! defined USE_FLOAT
40 # include "isnand-nolibm.h"
41 # define ISNAN isnand
42 # define FUNCTION "round"
43 # define DOUBLE_UINT uint64_t
44 # define DOUBLE_BITS 64
45 # define NUM_HIGHBITS 13
46 # define NUM_LOWBITS 4
47 #else /* defined USE_FLOAT */
48 # include "isnanf-nolibm.h"
49 # define ISNAN isnanf
50 # define FUNCTION "roundf"
51 # define DOUBLE_UINT uint32_t
52 # define DOUBLE_BITS 32
53 # define NUM_HIGHBITS 12
54 # define NUM_LOWBITS 4
55 #endif
57 /* Test for equality. */
58 static bool
59 equal (const char *message, DOUBLE x, DOUBLE y0, DOUBLE y1)
61 if (ISNAN (y0) ? ISNAN (y1) : y0 == y1)
62 return true;
63 else
65 #if GNULIB_TEST_FPRINTF_POSIX
66 fprintf (stderr, "%s: "FUNCTION"(%g(%a)) = %g(%a) or %g(%a)?\n",
67 message, x, x, y0, y0, y1, y1);
68 #endif
69 return false;
73 /* Test the function for a given argument. */
74 static bool
75 check (DOUBLE x)
77 DOUBLE ref1 = round_reference1 (x);
78 DOUBLE ref2 = round_reference2 (x);
79 DOUBLE result = ROUND (x);
81 /* If the reference implementations disagree, bail out immediately. */
82 if (!equal ("reference implementations disagree", x, ref1, ref2))
83 exit (EXIT_FAILURE);
85 /* If the actual implementation is wrong, return an error code. */
86 return equal ("bad round implementation", x, ref1, result);
89 int
90 main (void)
92 DOUBLE_UINT highbits, lowbits;
93 int error = 0;
94 for (highbits = 0; highbits < (1 << NUM_HIGHBITS); highbits++)
95 for (lowbits = 0; lowbits < (1 << NUM_LOWBITS); lowbits++)
97 /* Combine highbits and lowbits into a floating-point number,
98 sign-extending the lowbits to DOUBLE_BITS-NUM_HIGHBITS bits. */
99 union { DOUBLE f; DOUBLE_UINT i; } janus;
100 static_assert (sizeof janus.f == sizeof janus.i);
101 janus.i = lowbits | (highbits << (DOUBLE_BITS - NUM_HIGHBITS));
102 if (lowbits >> (NUM_LOWBITS - 1))
103 janus.i |= ((DOUBLE_UINT) -1
104 >> (NUM_LOWBITS + NUM_HIGHBITS)
105 << NUM_LOWBITS);
106 if (!check (janus.f))
107 error = true;
109 return (error ? 1 : 0);