]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////// |
2 | // Copyright 2012 John Maddock. Distributed under the Boost | |
3 | // Software License, Version 1.0. (See accompanying file | |
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ | |
5 | // | |
6 | ||
7 | #ifdef _MSC_VER | |
8 | # define _SCL_SECURE_NO_WARNINGS | |
9 | #endif | |
10 | ||
11 | #include <boost/detail/lightweight_test.hpp> | |
12 | #include <boost/array.hpp> | |
13 | #include "test.hpp" | |
14 | ||
15 | #include <boost/multiprecision/cpp_bin_float.hpp> | |
16 | #include <boost/multiprecision/cpp_dec_float.hpp> | |
17 | #include <boost/multiprecision/cpp_int.hpp> | |
18 | #include <boost/multiprecision/random.hpp> | |
19 | ||
20 | #ifdef TEST_GMP | |
21 | #include <boost/multiprecision/gmp.hpp> | |
22 | #endif | |
23 | #ifdef TEST_TOMMATH | |
24 | #include <boost/multiprecision/tommath.hpp> | |
25 | #endif | |
26 | #ifdef TEST_MPFR | |
27 | #include <boost/multiprecision/mpfr.hpp> | |
28 | #endif | |
29 | ||
30 | int main() | |
31 | { | |
32 | using namespace boost::multiprecision; | |
33 | using namespace boost::random; | |
34 | ||
35 | independent_bits_engine<mt11213b, 1024, cpp_int> gen; | |
36 | mt11213b small_gen; | |
37 | ||
38 | for(unsigned i = 0; i < 100; ++i) | |
39 | { | |
40 | cpp_int c = gen(); | |
41 | // | |
42 | // Integer to integer conversions first: | |
43 | // | |
44 | #ifdef TEST_GMP | |
45 | mpz_int z(c); | |
46 | cpp_int t(z); | |
47 | BOOST_CHECK_EQUAL(t, c); | |
48 | z.assign(-c); | |
49 | t.assign(-z); | |
50 | BOOST_CHECK_EQUAL(t, c); | |
51 | #endif | |
52 | #ifdef TEST_TOMMATH | |
53 | tom_int tom(c); | |
54 | cpp_int t2(tom); | |
55 | BOOST_CHECK_EQUAL(t2, c); | |
56 | tom.assign(-c); | |
57 | t2.assign(-tom); | |
58 | BOOST_CHECK_EQUAL(t2, c); | |
59 | #endif | |
60 | // | |
61 | // Now integer to float: | |
62 | // | |
63 | typedef number<cpp_dec_float<500> > dec_float_500; | |
64 | dec_float_500 df(c); | |
65 | dec_float_500 df2(c.str()); | |
66 | BOOST_CHECK_EQUAL(df, df2); | |
67 | df.assign(-c); | |
68 | df2 = -df2; | |
69 | BOOST_CHECK_EQUAL(df, df2); | |
70 | #ifdef TEST_GMP | |
71 | typedef number<gmp_float<500> > mpf_type; | |
72 | mpf_type mpf(c); | |
73 | mpf_type mpf2(c.str()); | |
74 | BOOST_CHECK_EQUAL(mpf, mpf2); | |
75 | mpf.assign(-c); | |
76 | mpf2 = -mpf2; | |
77 | BOOST_CHECK_EQUAL(mpf, mpf2); | |
78 | #endif | |
79 | #ifdef TEST_MPFR | |
80 | typedef number<mpfr_float_backend<500> > mpfr_type; | |
81 | mpfr_type mpfr(c); | |
82 | mpfr_type mpfr2(c.str()); | |
83 | BOOST_CHECK_EQUAL(mpfr, mpfr2); | |
84 | mpfr.assign(-c); | |
85 | mpfr2 = -mpfr2; | |
86 | BOOST_CHECK_EQUAL(mpfr, mpfr2); | |
87 | #endif | |
88 | // | |
89 | // Now float to float: | |
90 | // | |
91 | df.assign(c); | |
92 | df /= dec_float_500(gen()); | |
93 | dec_float_500 tol("1e-500"); | |
94 | #ifdef TEST_GMP | |
95 | mpf.assign(df); | |
96 | mpf2 = static_cast<mpf_type>(df.str()); | |
97 | BOOST_CHECK_EQUAL(mpf, mpf2); | |
98 | df.assign(mpf); | |
99 | df2 = static_cast<dec_float_500>(mpf.str()); | |
100 | BOOST_CHECK(fabs((df - df2) / df) < tol); | |
101 | #endif | |
102 | #ifdef TEST_MPFR | |
103 | mpfr.assign(df); | |
104 | mpfr2 = static_cast<mpfr_type>(df.str()); | |
105 | BOOST_CHECK_EQUAL(mpfr, mpfr2); | |
106 | df.assign(mpfr); | |
107 | df2 = static_cast<dec_float_500>(mpfr.str()); | |
108 | BOOST_CHECK(fabs((df - df2) / df) < tol); | |
109 | #endif | |
110 | // | |
111 | // Rational to rational conversions: | |
112 | // | |
113 | cpp_rational cppr(c, gen()), cppr2, cppr3; | |
114 | #ifdef TEST_GMP | |
115 | mpq_rational mpq(cppr); | |
116 | cppr2.assign(mpq); | |
117 | BOOST_CHECK_EQUAL(cppr, cppr2); | |
118 | #endif | |
119 | #ifdef TEST_TOMMATH | |
120 | tom_rational tr(cppr); | |
121 | cppr3.assign(tr); | |
122 | BOOST_CHECK_EQUAL(cppr, cppr3); | |
123 | #endif | |
124 | // | |
125 | // Integer to rational conversions: | |
126 | // | |
127 | #ifdef TEST_GMP | |
128 | mpq.assign(c); | |
129 | mpq_rational mpq2 = static_cast<mpq_rational>(c.str()); | |
130 | BOOST_CHECK_EQUAL(mpq, mpq2); | |
131 | #endif | |
132 | #ifdef TEST_TOMMATH | |
133 | tr.assign(c); | |
134 | tom_rational tr2 = static_cast<tom_rational>(c.str()); | |
135 | BOOST_CHECK_EQUAL(tr, tr2); | |
136 | #endif | |
137 | // | |
138 | // Rational to float: | |
139 | // | |
140 | df.assign(cppr); | |
141 | df2.assign(numerator(cppr)); | |
142 | df2 /= dec_float_500(denominator(cppr)); | |
143 | BOOST_CHECK(fabs(df - df2) / df2 < tol); | |
144 | // | |
145 | // Float to rational: | |
146 | // | |
147 | static const int max_range = std::numeric_limits<double>::digits >= std::numeric_limits<int>::digits ? std::numeric_limits<int>::max() : (1 << (std::numeric_limits<double>::digits - 1)) - 1; | |
148 | static const int min_range = std::numeric_limits<double>::digits >= std::numeric_limits<int>::digits ? std::numeric_limits<int>::min() : -(1 << (std::numeric_limits<double>::digits - 1)) + 1; | |
149 | static const boost::random::uniform_int_distribution<> i_val_dist(min_range, max_range); | |
150 | static const boost::random::uniform_int_distribution<> i_exp_dist(std::numeric_limits<double>::min_exponent, std::numeric_limits<double>::max_exponent - 2 - std::numeric_limits<int>::digits); | |
151 | int iv = i_val_dist(small_gen); | |
152 | int eval = i_exp_dist(small_gen); | |
153 | double dv = iv; | |
154 | dv = ldexp(dv, eval); | |
155 | cppr = dv; | |
156 | cppr2 = iv; | |
157 | cpp_int cppi = 1; | |
158 | cppi <<= abs(eval); | |
159 | if(eval < 0) | |
160 | cppr2 /= cppi; | |
161 | else | |
162 | cppr2 *= cppi; | |
163 | BOOST_CHECK_EQUAL(cppr, cppr2); | |
164 | // | |
165 | // Again but with bigger numbers: | |
166 | // | |
167 | cpp_int cppi2 = gen(); | |
168 | number<cpp_bin_float<1030> > cppbf(cppi2); | |
169 | cppbf = ldexp(cppbf, eval); | |
170 | cppr.assign(cppbf); | |
171 | cppr2 = cppi2; | |
172 | if(eval < 0) | |
173 | cppr2 /= cppi; | |
174 | else | |
175 | cppr2 *= cppi; | |
176 | BOOST_CHECK_EQUAL(cppr, cppr2); | |
177 | // | |
178 | // MSVC will compile either the code above, or | |
179 | // the code below, but not both in the same file. | |
180 | // Other compilers including Intel in msvc-compatibity | |
181 | // mode have no such difficulty. Indeed the fact that | |
182 | // the presence of the code below causes the code above to | |
183 | // fail to compile strongly suggests a compiler bug. | |
184 | // | |
185 | #if !defined(BOOST_MSVC) | |
186 | // | |
187 | // Again but with bigger base 10 numbers: | |
188 | // | |
189 | number<cpp_dec_float<std::numeric_limits<int1024_t>::digits10 + 3> > cppdec2(cppi2); | |
190 | cppdec2 = scalbn(cppdec2, eval); | |
191 | cppr.assign(cppdec2); | |
192 | cppr2 = cppi2; | |
193 | cppi = 10; | |
194 | cppi = pow(cppi, abs(eval)); | |
195 | if(eval < 0) | |
196 | cppr2 /= cppi; | |
197 | else | |
198 | cppr2 *= cppi; | |
199 | BOOST_CHECK_EQUAL(cppr, cppr2); | |
200 | #endif | |
201 | } | |
202 | ||
203 | return boost::report_errors(); | |
204 | } | |
205 | ||
206 | ||
207 |