]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////// |
2 | // Copyright 2012 John Maddock. Distributed under the Boost | |
3 | // Software License, Version 1.0. (See accompanying file | |
92f5a8d4 | 4 | // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt |
7c673cae FG |
5 | |
6 | #ifdef _MSC_VER | |
92f5a8d4 | 7 | #define _SCL_SECURE_NO_WARNINGS |
7c673cae FG |
8 | #endif |
9 | ||
10 | #ifdef HAS_FLOAT128 | |
11 | ||
12 | #include <boost/multiprecision/cpp_int.hpp> | |
13 | #include <boost/random/mersenne_twister.hpp> | |
14 | #include <boost/random/uniform_int.hpp> | |
15 | #include "test.hpp" | |
16 | ||
17 | #if defined(HAS_GMP) | |
18 | #include <boost/multiprecision/gmp.hpp> | |
19 | #endif | |
20 | #if defined(HAS_MPFR) | |
21 | #include <boost/multiprecision/mpfr.hpp> | |
22 | #endif | |
23 | #if defined(HAS_MPFI) | |
24 | #include <boost/multiprecision/mpfi.hpp> | |
25 | #endif | |
26 | #ifdef HAS_TOMMATH | |
27 | #include <boost/multiprecision/tommath.hpp> | |
28 | #endif | |
29 | #ifdef HAS_FLOAT128 | |
30 | #include <boost/multiprecision/float128.hpp> | |
31 | #endif | |
32 | #include <boost/multiprecision/cpp_bin_float.hpp> | |
33 | #include <boost/multiprecision/cpp_dec_float.hpp> | |
34 | ||
7c673cae FG |
35 | using namespace boost::multiprecision; |
36 | ||
37 | #ifdef BOOST_MSVC | |
92f5a8d4 | 38 | #pragma warning(disable : 4127) |
7c673cae FG |
39 | #endif |
40 | ||
7c673cae FG |
41 | template <class T> |
42 | T generate_random() | |
43 | { | |
92f5a8d4 | 44 | typedef int e_type; |
7c673cae | 45 | static boost::random::mt19937 gen; |
92f5a8d4 TL |
46 | T val = gen(); |
47 | T prev_val = -1; | |
48 | while (val != prev_val) | |
7c673cae FG |
49 | { |
50 | val *= (gen.max)(); | |
51 | prev_val = val; | |
52 | val += gen(); | |
53 | } | |
54 | e_type e; | |
55 | val = frexp(val, &e); | |
56 | ||
57 | static boost::random::uniform_int_distribution<e_type> ui(-20, 20); | |
58 | return ldexp(val, ui(gen)); | |
59 | } | |
60 | ||
61 | template <class From, class To> | |
1e59de90 | 62 | void test_convert_neg_int(From from, const std::integral_constant<bool, true>&) |
7c673cae FG |
63 | { |
64 | from = -from; | |
65 | To t3(from); | |
66 | To t4 = from.template convert_to<To>(); | |
67 | BOOST_CHECK_EQUAL(From(trunc(from)), From(t3)); | |
68 | BOOST_CHECK_EQUAL(From(trunc(from)), From(t4)); | |
69 | } | |
70 | template <class From, class To> | |
1e59de90 | 71 | void test_convert_neg_int(From const&, const std::integral_constant<bool, false>&) |
7c673cae FG |
72 | { |
73 | } | |
74 | ||
75 | template <class From, class To> | |
1e59de90 | 76 | void test_convert_imp(std::integral_constant<int, number_kind_floating_point> const&, std::integral_constant<int, number_kind_integer> const&) |
7c673cae | 77 | { |
92f5a8d4 | 78 | for (unsigned i = 0; i < 100; ++i) |
7c673cae FG |
79 | { |
80 | From from = generate_random<From>(); | |
92f5a8d4 TL |
81 | To t1(from); |
82 | To t2 = from.template convert_to<To>(); | |
7c673cae FG |
83 | BOOST_CHECK_EQUAL(From(trunc(from)), From(t1)); |
84 | BOOST_CHECK_EQUAL(From(trunc(from)), From(t2)); | |
1e59de90 | 85 | test_convert_neg_int<From, To>(from, std::integral_constant<bool, std::numeric_limits<From>::is_signed && std::numeric_limits<To>::is_signed > ()); |
7c673cae FG |
86 | } |
87 | } | |
88 | ||
89 | template <class From, class To> | |
1e59de90 | 90 | void test_convert_neg_rat(From from, const std::integral_constant<bool, true>&) |
7c673cae FG |
91 | { |
92 | from = -from; | |
93 | To t3(from); | |
94 | To t4 = from.template convert_to<To>(); | |
95 | BOOST_CHECK_EQUAL(From(t3), from); | |
96 | BOOST_CHECK_EQUAL(From(t4), from); | |
97 | } | |
98 | template <class From, class To> | |
1e59de90 | 99 | void test_convert_rat_int(From const&, const std::integral_constant<bool, false>&) |
7c673cae FG |
100 | { |
101 | } | |
102 | ||
103 | template <class From, class To> | |
1e59de90 | 104 | void test_convert_imp(std::integral_constant<int, number_kind_floating_point> const&, std::integral_constant<int, number_kind_rational> const&) |
7c673cae | 105 | { |
92f5a8d4 | 106 | for (unsigned i = 0; i < 100; ++i) |
7c673cae FG |
107 | { |
108 | From from = generate_random<From>(); | |
92f5a8d4 TL |
109 | To t1(from); |
110 | To t2 = from.template convert_to<To>(); | |
7c673cae FG |
111 | BOOST_CHECK_EQUAL(From(t1), from); |
112 | BOOST_CHECK_EQUAL(From(t2), from); | |
1e59de90 | 113 | test_convert_neg_rat<From, To>(from, std::integral_constant<bool, std::numeric_limits<From>::is_signed && std::numeric_limits<To>::is_signed > ()); |
7c673cae FG |
114 | } |
115 | } | |
116 | ||
117 | template <class From, class To> | |
1e59de90 | 118 | void test_convert_neg_float(From from, const std::integral_constant<bool, true>&) |
7c673cae FG |
119 | { |
120 | from = -from; | |
121 | To t3(from); | |
122 | To t4 = from.template convert_to<To>(); | |
123 | To answer(from.str()); | |
124 | To tol = (std::max)(std::numeric_limits<To>::epsilon(), To(std::numeric_limits<From>::epsilon())) * 2; | |
125 | BOOST_CHECK_CLOSE_FRACTION(t3, answer, tol); | |
126 | BOOST_CHECK_CLOSE_FRACTION(t4, answer, tol); | |
127 | } | |
128 | template <class From, class To> | |
1e59de90 | 129 | void test_convert_neg_float(From const&, const std::integral_constant<bool, false>&) |
7c673cae FG |
130 | { |
131 | } | |
132 | ||
133 | template <class From, class To> | |
1e59de90 | 134 | void test_convert_imp(std::integral_constant<int, number_kind_floating_point> const&, std::integral_constant<int, number_kind_floating_point> const&) |
7c673cae | 135 | { |
92f5a8d4 | 136 | for (unsigned i = 0; i < 100; ++i) |
7c673cae FG |
137 | { |
138 | From from = generate_random<From>(); | |
92f5a8d4 TL |
139 | To t1(from); |
140 | To t2 = from.template convert_to<To>(); | |
141 | To answer(from.str()); | |
142 | To tol = (std::max)(std::numeric_limits<To>::epsilon(), To(std::numeric_limits<From>::epsilon())) * 2; | |
7c673cae FG |
143 | BOOST_CHECK_CLOSE_FRACTION(t1, answer, tol); |
144 | BOOST_CHECK_CLOSE_FRACTION(t2, answer, tol); | |
1e59de90 | 145 | test_convert_neg_float<From, To>(from, std::integral_constant<bool, std::numeric_limits<From>::is_signed && std::numeric_limits<To>::is_signed > ()); |
7c673cae FG |
146 | } |
147 | } | |
148 | ||
149 | template <class From, class To> | |
150 | void test_convert() | |
151 | { | |
152 | test_convert_imp<From, To>(typename number_category<From>::type(), typename number_category<To>::type()); | |
153 | } | |
154 | ||
7c673cae FG |
155 | int main() |
156 | { | |
92f5a8d4 TL |
157 | // |
158 | // Some basic sanity checks first: | |
159 | // | |
160 | BOOST_CHECK_EQUAL(std::numeric_limits<float128>::epsilon(), float128("1.92592994438723585305597794258492732e-34")); | |
161 | BOOST_CHECK_EQUAL((std::numeric_limits<float128>::min)(), float128("3.36210314311209350626267781732175260e-4932")); | |
162 | BOOST_CHECK_EQUAL((std::numeric_limits<float128>::max)(), float128("1.18973149535723176508575932662800702e4932")); | |
163 | BOOST_CHECK_EQUAL((std::numeric_limits<float128>::denorm_min)(), float128("6.475175119438025110924438958227646552e-4966")); | |
164 | BOOST_CHECK((boost::math::isinf)((std::numeric_limits<float128>::infinity)())); | |
165 | BOOST_CHECK((std::numeric_limits<float128>::infinity)() > 0); | |
166 | BOOST_CHECK((boost::math::isnan)((std::numeric_limits<float128>::quiet_NaN)())); | |
167 | ||
7c673cae FG |
168 | test_convert<float128, cpp_int>(); |
169 | test_convert<float128, int128_t>(); | |
170 | test_convert<float128, uint128_t>(); | |
171 | ||
7c673cae FG |
172 | test_convert<float128, cpp_rational>(); |
173 | ||
174 | test_convert<float128, cpp_dec_float_50>(); | |
175 | ||
176 | #if defined(HAS_GMP) | |
177 | test_convert<float128, mpz_int>(); | |
178 | test_convert<float128, mpq_rational>(); | |
179 | test_convert<float128, mpf_float_50>(); | |
180 | #endif | |
181 | #if defined(HAS_MPFR) | |
182 | test_convert<float128, mpfr_float_50>(); | |
183 | #endif | |
184 | #if defined(HAS_MPFI) | |
185 | test_convert<float128, mpfi_float_50>(); | |
186 | #endif | |
187 | #ifdef HAS_TOMMATH | |
188 | test_convert<float128, tom_int>(); | |
189 | test_convert<float128, tom_rational>(); | |
190 | #endif | |
191 | return boost::report_errors(); | |
192 | } | |
193 | ||
194 | #else | |
195 | ||
196 | int main() { return 0; } | |
197 | ||
198 | #endif |