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