1 /* Test for the C++ implementation of iszero.
2 Copyright (C) 2016-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #define _GNU_SOURCE 1
20 #include <math.h>
21 #include <stdio.h>
22
23 #include <limits>
24
25 /* Support for _Float128 in std::numeric_limits is limited.
26 Include ieee754_float128.h and use the bitfields in the union
27 ieee854_float128.ieee_nan to build corner-case inputs. */
28 #if __HAVE_DISTINCT_FLOAT128
29 # include <ieee754_float128.h>
30 #endif
31
32 static bool errors;
33
34 static void
check(int actual,int expected,const char * actual_expr,int line)35 check (int actual, int expected, const char *actual_expr, int line)
36 {
37 if (actual != expected)
38 {
39 errors = true;
40 printf ("%s:%d: error: %s\n", __FILE__, line, actual_expr);
41 printf ("%s:%d: expected: %d\n", __FILE__, line, expected);
42 printf ("%s:%d: actual: %d\n", __FILE__, line, actual);
43 }
44 }
45
46 #define CHECK(actual, expected) \
47 check ((actual), (expected), #actual, __LINE__)
48
49 template <class T>
50 static void
check_type()51 check_type ()
52 {
53 typedef std::numeric_limits<T> limits;
54 CHECK (iszero (T{}), 1);
55 CHECK (iszero (T{0}), 1);
56 CHECK (iszero (T{-0.0}), 1);
57 CHECK (iszero (T{1}), 0);
58 CHECK (iszero (T{-1}), 0);
59 CHECK (iszero (limits::min ()), 0);
60 CHECK (iszero (-limits::min ()), 0);
61 CHECK (iszero (limits::max ()), 0);
62 CHECK (iszero (-limits::max ()), 0);
63 if (limits::has_infinity)
64 {
65 CHECK (iszero (limits::infinity ()), 0);
66 CHECK (iszero (-limits::infinity ()), 0);
67 }
68 CHECK (iszero (limits::epsilon ()), 0);
69 CHECK (iszero (-limits::epsilon ()), 0);
70 if (limits::has_quiet_NaN)
71 CHECK (iszero (limits::quiet_NaN ()), 0);
72 if (limits::has_signaling_NaN)
73 CHECK (iszero (limits::signaling_NaN ()), 0);
74 if (limits::has_signaling_NaN)
75 CHECK (iszero (limits::signaling_NaN ()), 0);
76 CHECK (iszero (limits::denorm_min ()),
77 std::numeric_limits<T>::has_denorm == std::denorm_absent);
78 CHECK (iszero (-limits::denorm_min ()),
79 std::numeric_limits<T>::has_denorm == std::denorm_absent);
80 }
81
82 #if __HAVE_DISTINCT_FLOAT128
83 static void
check_float128()84 check_float128 ()
85 {
86 ieee854_float128 q;
87
88 q.d = 0.0Q;
89 CHECK (iszero (q.d), 1);
90 q.d = -0.0Q;
91 CHECK (iszero (q.d), 1);
92 q.d = 1.0Q;
93 CHECK (iszero (q.d), 0);
94 q.d = -1.0Q;
95 CHECK (iszero (q.d), 0);
96
97 /* Normal min. */
98 q.ieee.negative = 0;
99 q.ieee.exponent = 0x0001;
100 q.ieee.mantissa0 = 0x0000;
101 q.ieee.mantissa1 = 0x00000000;
102 q.ieee.mantissa2 = 0x00000000;
103 q.ieee.mantissa3 = 0x00000000;
104 CHECK (iszero (q.d), 0);
105 q.ieee.negative = 1;
106 CHECK (iszero (q.d), 0);
107
108 /* Normal max. */
109 q.ieee.negative = 0;
110 q.ieee.exponent = 0x7FFE;
111 q.ieee.mantissa0 = 0xFFFF;
112 q.ieee.mantissa1 = 0xFFFFFFFF;
113 q.ieee.mantissa2 = 0xFFFFFFFF;
114 q.ieee.mantissa3 = 0xFFFFFFFF;
115 CHECK (iszero (q.d), 0);
116 q.ieee.negative = 1;
117 CHECK (iszero (q.d), 0);
118
119 /* Infinity. */
120 q.ieee.negative = 0;
121 q.ieee.exponent = 0x7FFF;
122 q.ieee.mantissa0 = 0x0000;
123 q.ieee.mantissa1 = 0x00000000;
124 q.ieee.mantissa2 = 0x00000000;
125 q.ieee.mantissa3 = 0x00000000;
126 CHECK (iszero (q.d), 0);
127
128 /* Quiet NaN. */
129 q.ieee_nan.quiet_nan = 1;
130 q.ieee_nan.mantissa0 = 0x0000;
131 CHECK (iszero (q.d), 0);
132
133 /* Signaling NaN. */
134 q.ieee_nan.quiet_nan = 0;
135 q.ieee_nan.mantissa0 = 0x4000;
136 CHECK (iszero (q.d), 0);
137
138 /* Denormal min. */
139 q.ieee.negative = 0;
140 q.ieee.exponent = 0x0000;
141 q.ieee.mantissa0 = 0x0000;
142 q.ieee.mantissa1 = 0x00000000;
143 q.ieee.mantissa2 = 0x00000000;
144 q.ieee.mantissa3 = 0x00000001;
145 CHECK (iszero (q.d), 0);
146 q.ieee.negative = 1;
147 CHECK (iszero (q.d), 0);
148 }
149 #endif
150
151 static int
do_test(void)152 do_test (void)
153 {
154 check_type<float> ();
155 check_type<double> ();
156 check_type<long double> ();
157 #if __HAVE_DISTINCT_FLOAT128
158 check_float128 ();
159 #endif
160 return errors;
161 }
162
163 #define TEST_FUNCTION do_test ()
164 #include "../test-skeleton.c"
165