1 /* Test of rounding to nearest, breaking ties away from zero.
2 Copyright (C) 2007-2017 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 <http://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
40 #ifdef USE_LONG_DOUBLE
41 # error Long double not supported.
42 #elif ! defined USE_FLOAT
43 # include "isnand-nolibm.h"
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"
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
60 /* Test for equality. */
62 equal (const char *message
, DOUBLE x
, DOUBLE y0
, DOUBLE y1
)
64 if (ISNAN (y0
) ? ISNAN (y1
) : y0
== y1
)
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
);
76 /* Test the function for a given argument. */
80 DOUBLE ref1
= round_reference1 (x
);
81 DOUBLE ref2
= round_reference2 (x
);
82 DOUBLE result
= ROUND (x
);
84 /* If the reference implementations disagree, bail out immediately. */
85 if (!equal ("reference implementations disagree", x
, ref1
, ref2
))
88 /* If the actual implementation is wrong, return an error code. */
89 return equal ("bad round implementation", x
, ref1
, result
);
95 DOUBLE_UINT highbits
, lowbits
;
97 for (highbits
= 0; highbits
< (1 << NUM_HIGHBITS
); highbits
++)
98 for (lowbits
= 0; lowbits
< (1 << NUM_LOWBITS
); lowbits
++)
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
)
109 if (!check (janus
.f
))
112 return (error
? 1 : 0);