1// Test for boost/core/cmath.hpp
2//
3// Copyright 2020 Peter Dimov
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#include <boost/core/cmath.hpp>
8#include <boost/core/lightweight_test.hpp>
9#include <boost/config.hpp>
10#include <boost/config/workaround.hpp>
11#include <limits>
12#include <cfloat>
13
14template<class T> void test_positive_normal( T x )
15{
16 BOOST_TEST( boost::core::isfinite( x ) );
17 BOOST_TEST( !boost::core::isinf( x ) );
18 BOOST_TEST( !boost::core::isnan( x ) );
19 BOOST_TEST( boost::core::isnormal( x ) );
20
21 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_normal );
22
23 BOOST_TEST( !boost::core::signbit( x ) );
24
25 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
26 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
27}
28
29template<class T> void test_negative_normal( T x )
30{
31 BOOST_TEST( boost::core::isfinite( x ) );
32 BOOST_TEST( !boost::core::isinf( x ) );
33 BOOST_TEST( !boost::core::isnan( x ) );
34 BOOST_TEST( boost::core::isnormal( x ) );
35
36 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_normal );
37
38 BOOST_TEST( boost::core::signbit( x ) );
39
40 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
41 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
42}
43
44template<class T> void test_positive_zero( T x )
45{
46 BOOST_TEST( boost::core::isfinite( x ) );
47 BOOST_TEST( !boost::core::isinf( x ) );
48 BOOST_TEST( !boost::core::isnan( x ) );
49 BOOST_TEST( !boost::core::isnormal( x ) );
50
51 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_zero );
52
53 BOOST_TEST( !boost::core::signbit( x ) );
54
55 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
56 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
57}
58
59template<class T> void test_negative_zero( T x )
60{
61 BOOST_TEST( boost::core::isfinite( x ) );
62 BOOST_TEST( !boost::core::isinf( x ) );
63 BOOST_TEST( !boost::core::isnan( x ) );
64 BOOST_TEST( !boost::core::isnormal( x ) );
65
66 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_zero );
67
68#if defined(BOOST_CORE_USE_GENERIC_CMATH) && BOOST_WORKAROUND(BOOST_GCC, < 40700)
69
70 // g++ 4.4, 4.6 fail these tests with optimizations on
71
72#else
73
74 BOOST_TEST( boost::core::signbit( x ) );
75
76 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
77 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
78
79#endif
80}
81
82template<class T> void test_positive_infinity( T x )
83{
84 BOOST_TEST( !boost::core::isfinite( x ) );
85 BOOST_TEST( boost::core::isinf( x ) );
86 BOOST_TEST( !boost::core::isnan( x ) );
87 BOOST_TEST( !boost::core::isnormal( x ) );
88
89 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_infinite );
90
91 BOOST_TEST( !boost::core::signbit( x ) );
92
93 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
94 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
95}
96
97template<class T> void test_negative_infinity( T x )
98{
99 BOOST_TEST( !boost::core::isfinite( x ) );
100 BOOST_TEST( boost::core::isinf( x ) );
101 BOOST_TEST( !boost::core::isnan( x ) );
102 BOOST_TEST( !boost::core::isnormal( x ) );
103
104 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_infinite );
105
106 BOOST_TEST( boost::core::signbit( x ) );
107
108 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
109 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
110}
111
112template<class T> void test_positive_nan( T x )
113{
114 BOOST_TEST( !boost::core::isfinite( x ) );
115 BOOST_TEST( !boost::core::isinf( x ) );
116 BOOST_TEST( boost::core::isnan( x ) );
117 BOOST_TEST( !boost::core::isnormal( x ) );
118
119 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_nan );
120
121 BOOST_TEST( !boost::core::signbit( x ) );
122
123 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
124 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
125}
126
127template<class T> void test_negative_nan( T x )
128{
129 BOOST_TEST( !boost::core::isfinite( x ) );
130 BOOST_TEST( !boost::core::isinf( x ) );
131 BOOST_TEST( boost::core::isnan( x ) );
132 BOOST_TEST( !boost::core::isnormal( x ) );
133
134 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_nan );
135
136 BOOST_TEST( boost::core::signbit( x ) );
137
138 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
139 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
140}
141
142template<class T> void test_positive_subnormal( T x )
143{
144 BOOST_TEST( boost::core::isfinite( x ) );
145 BOOST_TEST( !boost::core::isinf( x ) );
146 BOOST_TEST( !boost::core::isnan( x ) );
147 BOOST_TEST( !boost::core::isnormal( x ) );
148
149 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_subnormal );
150
151 BOOST_TEST( !boost::core::signbit( x ) );
152
153 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(+2) );
154 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(+2) );
155}
156
157template<class T> void test_negative_subnormal( T x )
158{
159 BOOST_TEST( boost::core::isfinite( x ) );
160 BOOST_TEST( !boost::core::isinf( x ) );
161 BOOST_TEST( !boost::core::isnan( x ) );
162 BOOST_TEST( !boost::core::isnormal( x ) );
163
164 BOOST_TEST_EQ( boost::core::fpclassify( x ), boost::core::fp_subnormal );
165
166 BOOST_TEST( boost::core::signbit( x ) );
167
168 BOOST_TEST_EQ( boost::core::copysign( T(+2), x ), T(-2) );
169 BOOST_TEST_EQ( boost::core::copysign( T(-2), x ), T(-2) );
170}
171
172template<class T> void test_positive_normal_( T x )
173{
174 test_positive_normal( x );
175 test_positive_normal( boost::core::copysign( x, T(+1) ) );
176 test_negative_normal( boost::core::copysign( x, T(-1) ) );
177}
178
179template<class T> void test_negative_normal_( T x )
180{
181 test_negative_normal( x );
182 test_positive_normal( boost::core::copysign( x, T(+1) ) );
183 test_negative_normal( boost::core::copysign( x, T(-1) ) );
184}
185
186template<class T> void test_positive_zero_( T x )
187{
188 test_positive_zero( x );
189 test_positive_zero( boost::core::copysign( x, T(+1) ) );
190 test_negative_zero( boost::core::copysign( x, T(-1) ) );
191}
192
193template<class T> void test_negative_zero_( T x )
194{
195 test_negative_zero( x );
196 test_positive_zero( boost::core::copysign( x, T(+1) ) );
197 test_negative_zero( boost::core::copysign( x, T(-1) ) );
198}
199
200template<class T> void test_positive_infinity_( T x )
201{
202 test_positive_infinity( x );
203 test_positive_infinity( boost::core::copysign( x, T(+1) ) );
204 test_negative_infinity( boost::core::copysign( x, T(-1) ) );
205}
206
207template<class T> void test_negative_infinity_( T x )
208{
209 test_negative_infinity( x );
210 test_positive_infinity( boost::core::copysign( x, T(+1) ) );
211 test_negative_infinity( boost::core::copysign( x, T(-1) ) );
212}
213
214template<class T> void test_positive_nan_( T x )
215{
216 test_positive_nan( x );
217 test_positive_nan( boost::core::copysign( x, T(+1) ) );
218 test_negative_nan( boost::core::copysign( x, T(-1) ) );
219}
220
221template<class T> void test_negative_nan_( T x )
222{
223 test_negative_nan( x );
224 test_positive_nan( boost::core::copysign( x, T(+1) ) );
225 test_negative_nan( boost::core::copysign( x, T(-1) ) );
226}
227
228template<class T> void test_positive_subnormal_( T x )
229{
230 test_positive_subnormal( x );
231 test_positive_subnormal( boost::core::copysign( x, T(+1) ) );
232 test_negative_subnormal( boost::core::copysign( x, T(-1) ) );
233}
234
235template<class T> void test_negative_subnormal_( T x )
236{
237 test_negative_subnormal( x );
238 test_positive_subnormal( boost::core::copysign( x, T(+1) ) );
239 test_negative_subnormal( boost::core::copysign( x, T(-1) ) );
240}
241
242int main()
243{
244 // float
245
246 test_positive_normal_( x: +1.0f );
247 test_negative_normal_( x: -1.0f );
248 test_positive_normal_( FLT_MIN );
249 test_negative_normal_( x: -FLT_MIN );
250 test_positive_normal_( FLT_MAX );
251 test_negative_normal_( x: -FLT_MAX );
252 test_positive_zero_( x: +0.0f );
253 test_negative_zero_( x: -0.0f );
254 test_positive_infinity_( x: std::numeric_limits<float>::infinity() );
255 test_negative_infinity_( x: -std::numeric_limits<float>::infinity() );
256 test_positive_nan_( x: std::numeric_limits<float>::quiet_NaN() );
257 test_negative_nan_( x: boost::core::copysign( x: std::numeric_limits<float>::quiet_NaN(), y: -1.0f ) );
258 test_positive_subnormal_( FLT_MIN / 2 );
259 test_negative_subnormal_( x: -FLT_MIN / 2 );
260
261 // double
262
263 test_positive_normal_( x: +1.0 );
264 test_negative_normal_( x: -1.0 );
265 test_positive_normal_( DBL_MIN );
266 test_negative_normal_( x: -DBL_MIN );
267 test_positive_normal_( DBL_MAX );
268 test_negative_normal_( x: -DBL_MAX );
269 test_positive_zero_( x: +0.0 );
270 test_negative_zero_( x: -0.0 );
271 test_positive_infinity_( x: std::numeric_limits<double>::infinity() );
272 test_negative_infinity_( x: -std::numeric_limits<double>::infinity() );
273 test_positive_nan_( x: std::numeric_limits<double>::quiet_NaN() );
274 test_negative_nan_( x: boost::core::copysign( x: std::numeric_limits<double>::quiet_NaN(), y: -1.0 ) );
275 test_positive_subnormal_( DBL_MIN / 2 );
276 test_negative_subnormal_( x: -DBL_MIN / 2 );
277
278 // long double
279
280 test_positive_normal_( x: +1.0l );
281 test_negative_normal_( x: -1.0l );
282 test_positive_normal_( LDBL_MIN );
283 test_negative_normal_( x: -LDBL_MIN );
284 test_positive_normal_( LDBL_MAX );
285 test_negative_normal_( x: -LDBL_MAX );
286 test_positive_zero_( x: +0.0l );
287 test_negative_zero_( x: -0.0l );
288 test_positive_infinity_( x: std::numeric_limits<long double>::infinity() );
289 test_negative_infinity_( x: -std::numeric_limits<long double>::infinity() );
290 test_positive_nan_( x: std::numeric_limits<long double>::quiet_NaN() );
291 test_negative_nan_( x: boost::core::copysign( x: std::numeric_limits<long double>::quiet_NaN(), y: -1.0l ) );
292 test_positive_subnormal_( LDBL_MIN / 2 );
293 test_negative_subnormal_( x: -LDBL_MIN / 2 );
294
295 return boost::report_errors();
296}
297

source code of boost/libs/core/test/cmath_test.cpp