• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define BOOST_TEST_MAIN// Copyright John Maddock 2008
2 //  (C) Copyright Paul A. Bristow 2011 (added tests for changesign)
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #include <boost/math/concepts/real_concept.hpp> // for real_concept
9 #include <boost/math/special_functions/sign.hpp>
10 
11 #define BOOST_TEST_MAIN
12 #include <boost/test/unit_test.hpp> // Boost.Test
13 #include <boost/test/results_collector.hpp>
14 #include <boost/test/unit_test.hpp>
15 #include <boost/test/tools/floating_point_comparison.hpp>
16 
17 #include <iostream>
18    using std::cout;
19    using std::endl;
20    using std::setprecision;
21 
22 template <class RealType>
test_spots(RealType,const char *)23 void test_spots(RealType /*T*/, const char* /*type_name*/)
24 {
25    // Basic sanity checks.
26    RealType a = 0;
27    RealType b = 1;
28    RealType c = -1;
29    BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
30    BOOST_CHECK_EQUAL((boost::math::sign)(a), 0);
31    BOOST_CHECK_EQUAL((boost::math::changesign)(b), RealType(-1));
32    BOOST_CHECK_EQUAL((boost::math::changesign)(c), RealType(+1));
33    BOOST_CHECK_EQUAL((boost::math::changesign)(a), RealType(0));
34 
35    // Compare to formula for changsign(x) = copysign(x, signbit(x) ? 1.0 : -1.0)
36    BOOST_CHECK_EQUAL((boost::math::changesign)(b),
37       (boost::math::copysign)(b, (boost::math::signbit)(b) ? RealType(1.) : RealType(-1.) ));
38 
39 
40    BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
41    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
42    a = 1;
43    BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
44    BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
45    BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
46    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
47    a = -1;
48    BOOST_CHECK((boost::math::signbit)(a) != 0);
49    BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
50    BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
51    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
52    a = boost::math::tools::max_value<RealType>();
53    BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
54    BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
55    BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
56    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
57    a = -boost::math::tools::max_value<RealType>();
58    BOOST_CHECK((boost::math::signbit)(a) != 0);
59    BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
60    BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
61    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
62 
63    if(std::numeric_limits<RealType>::has_infinity)
64    {
65       a = std::numeric_limits<RealType>::infinity();
66       BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
67       BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
68       BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
69       BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
70       BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a);
71 
72       a = -std::numeric_limits<RealType>::infinity();
73       BOOST_CHECK((boost::math::signbit)(a) != 0);
74       BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
75       BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
76       BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
77       BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a);
78    }
79 #if !defined(__SUNPRO_CC) && !defined(BOOST_INTEL)
80    if(std::numeric_limits<RealType>::has_quiet_NaN)
81    {
82       a = std::numeric_limits<RealType>::quiet_NaN();
83       BOOST_CHECK_EQUAL((boost::math::signbit)(a), 0);
84       BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
85       BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(1));
86       BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
87       // BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a); // NaN comparison fails always!
88       BOOST_CHECK((boost::math::signbit)((boost::math::changesign)(a)) != 0);
89 
90       a = -std::numeric_limits<RealType>::quiet_NaN();
91       BOOST_CHECK((boost::math::signbit)(a) != 0);
92       BOOST_CHECK_EQUAL((boost::math::sign)(a), -1);
93       BOOST_CHECK_EQUAL((boost::math::copysign)(b, a), RealType(-1));
94       BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(-1));
95       //BOOST_CHECK_EQUAL((boost::math::changesign)(a), -a); // NaN comparison fails always!
96       BOOST_CHECK_EQUAL((boost::math::signbit)((boost::math::changesign)(a)), 0);
97 
98    }
99 #endif
100    //
101    // Try some extreme values:
102    //
103    a = boost::math::tools::min_value<RealType>();
104    b = -a;
105    c = -1;
106    BOOST_CHECK((boost::math::signbit)(a) == 0);
107    BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
108    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
109    BOOST_CHECK((boost::math::signbit)(b) != 0);
110    BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
111    c = 1;
112    BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
113    //
114    // try denormalised values:
115    //
116    a /= 4;
117    if(a != 0)
118    {
119       b = -a;
120       c = -1;
121       BOOST_CHECK((boost::math::signbit)(a) == 0);
122       BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
123       BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
124       BOOST_CHECK((boost::math::signbit)(b) != 0);
125       BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
126       c = 1;
127       BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
128    }
129    a = boost::math::tools::max_value<RealType>() / 2;
130    b = -a;
131    c = -1;
132    BOOST_CHECK((boost::math::signbit)(a) == 0);
133    BOOST_CHECK_EQUAL((boost::math::sign)(a), 1);
134    BOOST_CHECK_EQUAL((boost::math::copysign)(c, a), RealType(1));
135    BOOST_CHECK((boost::math::signbit)(b) != 0);
136    BOOST_CHECK_EQUAL((boost::math::sign)(b), -1);
137    c = 1;
138    BOOST_CHECK_EQUAL((boost::math::copysign)(c, b), RealType(-1));
139 }
140 
141 
BOOST_AUTO_TEST_CASE(test_main)142 BOOST_AUTO_TEST_CASE( test_main )
143 {
144    // Basic sanity-check spot values.
145    // (Parameter value, arbitrarily zero, only communicates the floating point type).
146    test_spots(0.0F, "float"); // Test float. OK at decdigits = 0 tolerance = 0.0001 %
147    test_spots(0.0, "double"); // Test double. OK at decdigits 7, tolerance = 1e07 %
148    // long double support for the sign functions is considered "core" so we always test it
149    // even when long double support is turned off via BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
150    test_spots(0.0L, "long double"); // Test long double.
151 #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
152    test_spots(boost::math::concepts::real_concept(0), "real_concept"); // Test real_concept.
153 #endif
154 
155 
156 } // BOOST_AUTO_TEST_CASE( test_main )
157 
158