]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/test/test_signed_zero.cpp
1 // Copyright 2006 Johan Rade
2 // Copyright 2011 Paul A. Bristow To incorporate into Boost.Math
3 // Copyright 2012 Paul A. Bristow with new tests.
5 // Distributed under the Boost Software License, Version 1.0.
6 // (See accompanying file LICENSE_1_0.txt
7 // or copy at http://www.boost.org/LICENSE_1_0.txt)
10 # pragma warning(disable : 4127) // Expression is constant.
13 #define BOOST_TEST_MAIN
15 #include <boost/test/unit_test.hpp>
16 #include <boost/math/special_functions/nonfinite_num_facets.hpp>
17 #include "s_.ipp" // To create test strings like std::basic_string<CharType> s = S_("0 -0");
30 // Using an anonymous namespace resolves ambiguities on platforms
31 // with fpclassify etc functions at global scope.
33 using namespace boost::math
;
34 using boost::math::signbit
;
35 using boost::math::changesign
;
36 using boost::math::isnan
;
38 //------------------------------------------------------------------------------
40 template<class CharType
, class ValType
> void signed_zero_test_impl();
41 // Loopback tests using all built-in char and floating-point types.
43 BOOST_AUTO_TEST_CASE(signed_zero_test
)
46 << "BuildInfo:" << '\n'
47 << " platform " << BOOST_PLATFORM
<< '\n'
48 << " compiler " << BOOST_COMPILER
<< '\n'
49 << " STL " << BOOST_STDLIB
<< '\n'
50 << " Boost version " << BOOST_VERSION
/100000 << "."
51 << BOOST_VERSION
/100 % 1000 << "."
52 << BOOST_VERSION
% 100
55 signed_zero_test_impl
<char, float>();
56 signed_zero_test_impl
<char, double>();
57 signed_zero_test_impl
<char, long double>();
58 signed_zero_test_impl
<wchar_t, float>();
59 signed_zero_test_impl
<wchar_t, double>();
60 signed_zero_test_impl
<wchar_t, long double>();
63 template<class CharType
, class ValType
> void signed_zero_test_impl()
67 if (signbit(static_cast<CharType
>(-1e-6f
) / (std::numeric_limits
<CharType
>::max
)()) != -0)
69 BOOST_TEST_MESSAGE("Signed zero is not supported on this platform!");
73 std::locale old_locale
;
74 std::locale
tmp_locale(
75 old_locale
, new nonfinite_num_put
<CharType
>(signed_zero
));
76 std::locale
new_locale(tmp_locale
, new nonfinite_num_get
<CharType
>);
78 std::basic_stringstream
<CharType
> ss
;
81 std::basic_string
<CharType
> null
= S_("");
83 std::basic_string
<CharType
> s1
= S_("123");
84 ss
<< s1
<< std::endl
;
88 BOOST_CHECK(ss
.str() == null
); //
90 ValType a1
= static_cast<ValType
>(0); // zero.
91 ValType a2
= (changesign
)(static_cast<ValType
>(0)); // negative signed zero.
92 BOOST_CHECK(!(signbit
)(a1
)); //
93 BOOST_CHECK((signbit
)(a2
));
95 ss
<< a1
<< ' ' << a2
;
97 std::basic_string
<CharType
> s
= S_("0 -0"); // Expected.
98 BOOST_CHECK(ss
.str() == s
);
101 ss
>> b1
>> b2
; // Read back in.
103 BOOST_CHECK(b1
== a1
);
104 BOOST_CHECK(b2
== a2
);
105 BOOST_CHECK(!(signbit
)(b1
));
106 BOOST_CHECK((signbit
)(b2
));
107 BOOST_CHECK(ss
.rdstate() == std::ios_base::eofbit
);
108 } // template<class CharType, class ValType> void signed_zero_test_impl()
110 // Checking output of types char using first default & then using signed_zero flag.
111 #define CHECKOUT(manips, expected)\
114 std::locale old_locale;\
115 std::locale tmp_locale(old_locale, new nonfinite_num_put<char>(0));\
116 std::locale new_locale(tmp_locale, new nonfinite_num_get<char>);\
117 std::ostringstream ss;\
118 ss.imbue(new_locale);\
120 std::basic_string<char> s = S_(expected);\
121 BOOST_CHECK_EQUAL(ss.str(), s);\
124 std::locale old_locale;\
125 std::locale tmp_locale(old_locale, new nonfinite_num_put<char>(signed_zero));\
126 std::locale new_locale(tmp_locale, new nonfinite_num_get<char>);\
127 std::ostringstream ss;\
128 ss.imbue(new_locale);\
130 std::basic_string<char> s = S_(expected);\
131 BOOST_CHECK_EQUAL(ss.str(), s);\
135 BOOST_AUTO_TEST_CASE(misc_output_tests)
136 { // Tests of output using a variety of output options.
139 // STD libraries don't all format zeros the same,
140 // so figure out what the library-specific formatting is
141 // and then make sure that our facet produces the same...
143 bool precision_after
= false; // Prints N digits after the point rather than N digits total
144 bool triple_exponent
= false; // Has 3 digits in the exponent rather than 2.
145 std::stringstream ss
;
146 ss
<< std::showpoint
<< std::setprecision(6) << 0.0;
147 if(ss
.str().size() == 8)
148 precision_after
= true;
150 ss
<< std::scientific
<< 0.0;
151 triple_exponent
= ss
.str().size() - ss
.str().find_first_of('e') == 5;
156 CHECKOUT(0, "0"); // integer zero.
157 CHECKOUT(0., "0"); // double zero.
158 CHECKOUT(std::setw(2) << 0., " 0");
159 CHECKOUT(std::setw(4) << 0., " 0");
160 CHECKOUT(std::right
<< std::setw(4) << 0., " 0");
161 CHECKOUT(std::left
<< std::setw(4) << 0., "0 ");
162 CHECKOUT(std::setw(4) << std::setfill('*') << 0., "***0");
163 CHECKOUT(std::setw(4) << std::internal
<< std::setfill('*') << 0., "***0"); // left adjust sign and right adjust value.
164 CHECKOUT(std::showpos
<< std::setw(4) << std::internal
<< std::setfill('*') << 0., "+**0"); // left adjust sign and right adjust value.
168 // BOOST_STDLIB == ("Dinkumware standard library version" BOOST_STRINGIZE(_CPPLIB_VER)) )
169 CHECKOUT(std::showpoint
<< 0., "0.000000"); // std::setprecision(6)
170 CHECKOUT(std::setprecision(2) << std::showpoint
<< 0., "0.00");
174 CHECKOUT(std::showpoint
<< 0., "0.00000"); // std::setprecision(6)
175 CHECKOUT(std::setprecision(2) << std::showpoint
<< 0., "0.0");
177 CHECKOUT(std::fixed
<< std::setw(5) << std::setfill('0') << std::setprecision(2) << 0., "00.00");
178 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('0') << std::setprecision(2) << 0., "000.00");
179 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('0') << std::setprecision(3) << 0., "00.000");
180 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(3) << 0., "*0.000");
181 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 0.0, "0.00**");
183 CHECKOUT(std::showpos
<< 0., "+0");
184 CHECKOUT(std::showpos
<< std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 0.0, "+0.00*");
187 CHECKOUT(std::scientific
<< std::showpoint
<< std::setw(10) << std::setfill('*') << std::setprecision(1) << std::left
<< 0., "0.0e+000**");
191 CHECKOUT(std::scientific
<< std::showpoint
<< std::setw(10) << std::setfill('*') << std::setprecision(1) << std::left
<< 0., "0.0e+00***");
193 CHECKOUT(std::fixed
<< std::showpoint
<< std::setw(6) << std::setfill('*') << std::setprecision(3) << std::left
<< 0., "0.000*");
195 double nz
= (changesign
)(static_cast<double>(0)); // negative signed zero.
197 // CHECKOUT(std::defaultfloat << nz, "-0"); Only for C++11
198 CHECKOUT(std::showpos
<< nz
, "-0"); // Ignore showpos because is negative.
199 CHECKOUT(std::setw(2) << nz
, "-0");
200 CHECKOUT(std::setw(4) << nz
, " -0");
201 CHECKOUT(std::right
<< std::setw(4) << nz
, " -0");
202 CHECKOUT(std::left
<< std::setw(4) << nz
, "-0 ");
203 CHECKOUT(std::setw(4) << std::setfill('*') << nz
, "**-0");
204 CHECKOUT(std::setw(4) << std::internal
<< std::setfill('*') << nz
, "-**0"); // Use std::internal to left adjust sign and right adjust value.
205 CHECKOUT(std::showpos
<< std::setw(4) << std::internal
<< std::setfill('*') << nz
, "-**0");
207 CHECKOUT(std::fixed
<< std::setw(5) << std::setfill('0') << std::setprecision(2) << 0., "00.00");
208 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('0') << std::setprecision(2) << 0., "000.00");
209 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('0') << std::setprecision(3) << 0., "00.000");
210 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(3) << 0., "*0.000");
211 CHECKOUT(std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 0.0, "0.00**");
212 CHECKOUT(std::setprecision(2) << nz
, "-0"); // No showpoint, so no decimal point nor trailing zeros.
215 CHECKOUT(std::setprecision(2) << std::showpoint
<< nz
, "-0.00"); // or "-0.0"
216 CHECKOUT(std::setw(1) << std::setprecision(3) << std::showpoint
<< nz
, "-0.000"); // Not enough width for precision overflows width. or "-0.00"
220 CHECKOUT(std::setprecision(2) << std::showpoint
<< nz
, "-0.0"); // or "-0.00"
221 CHECKOUT(std::setw(1) << std::setprecision(3) << std::showpoint
<< nz
, "-0.00"); // Not enough width for precision overflows width. or "-0.000"
225 CHECKOUT(std::scientific
<< std::showpoint
<< std::setw(10) << std::setfill('*') << std::setprecision(1) << std::left
<< nz
, "-0.0e+000*"); // -0.0e+00**
229 CHECKOUT(std::scientific
<< std::showpoint
<< std::setw(10) << std::setfill('*') << std::setprecision(1) << std::left
<< nz
, "-0.0e+00**"); // -0.0e+000*
231 CHECKOUT(std::fixed
<< std::showpoint
<< std::setw(6) << std::setfill('*') << std::setprecision(3) << std::left
<< 0., "0.000*");
235 CHECKOUT(std::showpos
<< std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 42., "+42.00");
236 CHECKOUT(std::showpos
<< std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 4.2, "+4.20*");
237 CHECKOUT(std::showpos
<< std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 1.22, "+1.22*");
238 CHECKOUT(std::showpos
<< std::fixed
<< std::setw(6) << std::setfill('*') << std::setprecision(2) << std::left
<< 0.12, "+0.12*");
240 CHECKOUT(std::setprecision(4) << std::showpoint
<< 1.2, "1.200");
244 } // anonymous namespace
251 Running 2 test cases...
253 Compiler: Microsoft Visual C++ version 10.0
254 STL : Dinkumware standard library version 520
256 Entering test suite "Master Test Suite"
257 Entering test case "signed_zero_test"
258 Leaving test case "signed_zero_test"; testing time: 2ms
259 Entering test case "misc_output_tests"
260 Leaving test case "misc_output_tests"; testing time: 15ms
261 Leaving test suite "Master Test Suite"
263 *** No errors detected