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_
7 // Compare arithmetic results using fixed_int to GMP results.
11 # define _SCL_SECURE_NO_WARNINGS
15 // This ensures all our code gets tested, even though it may
16 // not be the fastest configuration in normal use:
18 #define BOOST_MP_USE_LIMB_SHIFT
20 #include <boost/multiprecision/gmp.hpp>
21 #include <boost/multiprecision/cpp_int.hpp>
22 #include <boost/random/mersenne_twister.hpp>
23 #include <boost/random/uniform_int.hpp>
24 #include <boost/timer.hpp>
28 #pragma warning(disable:4127) // Conditional expression is constant
31 #if !defined(TEST1) && !defined(TEST2) && !defined(TEST3)
38 T
generate_random(unsigned bits_wanted
)
40 static boost::random::mt19937 gen
;
41 typedef boost::random::mt19937::result_type random_type
;
45 if(std::numeric_limits
<T
>::is_bounded
&& (bits_wanted
== (unsigned)std::numeric_limits
<T
>::digits
))
47 max_val
= (std::numeric_limits
<T
>::max
)();
48 digits
= std::numeric_limits
<T
>::digits
;
52 max_val
= T(1) << bits_wanted
;
56 unsigned bits_per_r_val
= std::numeric_limits
<random_type
>::digits
- 1;
57 while((random_type(1) << bits_per_r_val
) > (gen
.max
)()) --bits_per_r_val
;
59 unsigned terms_needed
= digits
/ bits_per_r_val
+ 1;
62 for(unsigned i
= 0; i
< terms_needed
; ++i
)
72 struct is_checked_cpp_int
: public boost::mpl::false_
{};
73 template <unsigned MinBits
, unsigned MaxBits
, boost::multiprecision::cpp_integer_type SignType
, class Allocator
, boost::multiprecision::expression_template_option ET
>
74 struct is_checked_cpp_int
<boost::multiprecision::number
<boost::multiprecision::cpp_int_backend
<MinBits
, MaxBits
, SignType
, boost::multiprecision::checked
, Allocator
>, ET
> > : public boost::mpl::true_
{};
76 template <class Number
>
79 typedef Number test_type
;
80 typedef typename
test_type::backend_type::checked_type checked
;
82 unsigned last_error_count
;
85 boost::multiprecision::mpz_int a
, b
, c
, d
;
88 test_type a1
, b1
, c1
, d1
;
93 using namespace boost::multiprecision
;
94 BOOST_CHECK_EQUAL(a
.str(), a1
.str());
95 BOOST_CHECK_EQUAL(b
.str(), b1
.str());
96 BOOST_CHECK_EQUAL(c
.str(), c1
.str());
97 BOOST_CHECK_EQUAL(d
.str(), d1
.str());
98 BOOST_CHECK_EQUAL(mpz_int(a
+b
).str(), test_type(a1
+ b1
).str());
99 BOOST_CHECK_EQUAL((mpz_int(a
)+=b
).str(), (test_type(a1
) += b1
).str());
100 BOOST_CHECK_EQUAL((mpz_int(b
)+=a
).str(), (test_type(b1
) += a1
).str());
101 BOOST_CHECK_EQUAL(mpz_int(a
-b
).str(), test_type(a1
- b1
).str());
102 BOOST_CHECK_EQUAL((mpz_int(a
)-=b
).str(), (test_type(a1
) -= b1
).str());
103 BOOST_CHECK_EQUAL(mpz_int(mpz_int(-a
)+b
).str(), test_type(test_type(-a1
) + b1
).str());
104 BOOST_CHECK_EQUAL(mpz_int(mpz_int(-a
)-b
).str(), test_type(test_type(-a1
) - b1
).str());
105 BOOST_CHECK_EQUAL(mpz_int(c
* d
).str(), test_type(c1
* d1
).str());
106 BOOST_CHECK_EQUAL((mpz_int(c
)*=d
).str(), (test_type(c1
) *= d1
).str());
107 BOOST_CHECK_EQUAL((mpz_int(d
)*=c
).str(), (test_type(d1
) *= c1
).str());
108 BOOST_CHECK_EQUAL(mpz_int(c
* -d
).str(), test_type(c1
* -d1
).str());
109 BOOST_CHECK_EQUAL(mpz_int(-c
* d
).str(), test_type(-c1
* d1
).str());
110 BOOST_CHECK_EQUAL((mpz_int(c
)*=-d
).str(), (test_type(c1
) *= -d1
).str());
111 BOOST_CHECK_EQUAL((mpz_int(-d
)*=c
).str(), (test_type(-d1
) *= c1
).str());
112 BOOST_CHECK_EQUAL(mpz_int(b
* c
).str(), test_type(b1
* c1
).str());
113 BOOST_CHECK_EQUAL(mpz_int(a
/ b
).str(), test_type(a1
/ b1
).str());
114 BOOST_CHECK_EQUAL((mpz_int(a
)/=b
).str(), (test_type(a1
) /= b1
).str());
115 BOOST_CHECK_EQUAL(mpz_int(a
/ -b
).str(), test_type(a1
/ -b1
).str());
116 BOOST_CHECK_EQUAL(mpz_int(-a
/ b
).str(), test_type(-a1
/ b1
).str());
117 BOOST_CHECK_EQUAL((mpz_int(a
)/=-b
).str(), (test_type(a1
) /= -b1
).str());
118 BOOST_CHECK_EQUAL((mpz_int(-a
)/=b
).str(), (test_type(-a1
) /= b1
).str());
119 BOOST_CHECK_EQUAL(mpz_int(a
/ d
).str(), test_type(a1
/ d1
).str());
120 BOOST_CHECK_EQUAL(mpz_int(a
% b
).str(), test_type(a1
% b1
).str());
121 BOOST_CHECK_EQUAL((mpz_int(a
)%=b
).str(), (test_type(a1
) %= b1
).str());
122 BOOST_CHECK_EQUAL(mpz_int(a
% -b
).str(), test_type(a1
% -b1
).str());
123 BOOST_CHECK_EQUAL((mpz_int(a
)%=-b
).str(), (test_type(a1
) %= -b1
).str());
124 BOOST_CHECK_EQUAL(mpz_int(-a
% b
).str(), test_type(-a1
% b1
).str());
125 BOOST_CHECK_EQUAL((mpz_int(-a
)%=b
).str(), (test_type(-a1
) %= b1
).str());
126 BOOST_CHECK_EQUAL(mpz_int(a
% d
).str(), test_type(a1
% d1
).str());
127 BOOST_CHECK_EQUAL((mpz_int(a
)%=d
).str(), (test_type(a1
) %= d1
).str());
129 if(!std::numeric_limits
<test_type
>::is_bounded
)
131 test_type p
= a1
* b1
;
133 divide_qr(p
, b1
, p
, r
);
134 BOOST_CHECK_EQUAL(p
, a1
);
135 BOOST_CHECK_EQUAL(r
, test_type(0));
138 divide_qr(p
, d1
, p
, r
);
139 BOOST_CHECK_EQUAL(p
, a1
);
140 BOOST_CHECK_EQUAL(r
, test_type(0));
142 divide_qr(p
, test_type(1), p
, r
);
143 BOOST_CHECK_EQUAL(p
, a1
);
144 BOOST_CHECK_EQUAL(r
, test_type(0));
150 using namespace boost::multiprecision
;
152 BOOST_CHECK_EQUAL(mpz_int(a
|b
).str(), test_type(a1
| b1
).str());
153 BOOST_CHECK_EQUAL((mpz_int(a
)|=b
).str(), (test_type(a1
) |= b1
).str());
154 if(!is_checked_cpp_int
<test_type
>::value
)
156 BOOST_CHECK_EQUAL(mpz_int(-a
|b
).str(), test_type(-a1
| b1
).str());
157 BOOST_CHECK_EQUAL((mpz_int(-a
)|=b
).str(), (test_type(-a1
) |= b1
).str());
158 BOOST_CHECK_EQUAL(mpz_int(a
|-b
).str(), test_type(a1
| -b1
).str());
159 BOOST_CHECK_EQUAL((mpz_int(a
)|=-b
).str(), (test_type(a1
) |= -b1
).str());
160 BOOST_CHECK_EQUAL(mpz_int(-a
|-b
).str(), test_type(-a1
| -b1
).str());
161 BOOST_CHECK_EQUAL((mpz_int(-a
)|=-b
).str(), (test_type(-a1
) |= -b1
).str());
163 BOOST_CHECK_EQUAL(mpz_int(a
&b
).str(), test_type(a1
& b1
).str());
164 BOOST_CHECK_EQUAL((mpz_int(a
)&=b
).str(), (test_type(a1
) &= b1
).str());
165 if(!is_checked_cpp_int
<test_type
>::value
)
167 BOOST_CHECK_EQUAL(mpz_int(-a
&b
).str(), test_type(-a1
& b1
).str());
168 BOOST_CHECK_EQUAL((mpz_int(-a
)&=b
).str(), (test_type(-a1
) &= b1
).str());
169 BOOST_CHECK_EQUAL(mpz_int(a
&-b
).str(), test_type(a1
& -b1
).str());
170 BOOST_CHECK_EQUAL((mpz_int(a
)&=-b
).str(), (test_type(a1
) &= -b1
).str());
171 BOOST_CHECK_EQUAL(mpz_int(-a
&-b
).str(), test_type(-a1
& -b1
).str());
172 BOOST_CHECK_EQUAL((mpz_int(-a
)&=-b
).str(), (test_type(-a1
) &= -b1
).str());
174 BOOST_CHECK_EQUAL(mpz_int(a
^b
).str(), test_type(a1
^ b1
).str());
175 BOOST_CHECK_EQUAL((mpz_int(a
)^=b
).str(), (test_type(a1
) ^= b1
).str());
176 if(!is_checked_cpp_int
<test_type
>::value
)
178 BOOST_CHECK_EQUAL(mpz_int(-a
^b
).str(), test_type(-a1
^ b1
).str());
179 BOOST_CHECK_EQUAL((mpz_int(-a
)^=b
).str(), (test_type(-a1
) ^= b1
).str());
180 BOOST_CHECK_EQUAL(mpz_int(a
^-b
).str(), test_type(a1
^ -b1
).str());
181 BOOST_CHECK_EQUAL((mpz_int(a
)^=-b
).str(), (test_type(a1
) ^= -b1
).str());
182 BOOST_CHECK_EQUAL(mpz_int(-a
^-b
).str(), test_type(-a1
^ -b1
).str());
183 BOOST_CHECK_EQUAL((mpz_int(-a
)^=-b
).str(), (test_type(-a1
) ^= -b1
).str());
186 for(unsigned i
= 0; i
< 128; ++i
)
188 if(!std::numeric_limits
<test_type
>::is_bounded
)
190 BOOST_CHECK_EQUAL(mpz_int(a
<< i
).str(), test_type(a1
<< i
).str());
191 BOOST_CHECK_EQUAL(mpz_int(-a
<< i
).str(), test_type(-a1
<< i
).str());
193 else if(!is_checked_cpp_int
<test_type
>::value
)
195 test_type
t1(mpz_int(a
<< i
).str());
196 test_type t2
= a1
<< i
;
197 BOOST_CHECK_EQUAL(t1
, t2
);
198 t1
= test_type(mpz_int(-a
<< i
).str());
200 BOOST_CHECK_EQUAL(t1
, t2
);
202 BOOST_CHECK_EQUAL(mpz_int(a
>> i
).str(), test_type(a1
>> i
).str());
203 if(!is_checked_cpp_int
<test_type
>::value
)
205 BOOST_CHECK_EQUAL(mpz_int(-a
>> i
).str(), test_type(-a1
>> i
).str());
209 BOOST_CHECK_EQUAL(mpz_int(gcd(a
, b
)).str(), test_type(gcd(a1
, b1
)).str());
210 BOOST_CHECK_EQUAL(mpz_int(lcm(c
, d
)).str(), test_type(lcm(c1
, d1
)).str());
211 BOOST_CHECK_EQUAL(mpz_int(gcd(-a
, b
)).str(), test_type(gcd(-a1
, b1
)).str());
212 BOOST_CHECK_EQUAL(mpz_int(lcm(-c
, d
)).str(), test_type(lcm(-c1
, d1
)).str());
213 BOOST_CHECK_EQUAL(mpz_int(gcd(-a
, -b
)).str(), test_type(gcd(-a1
, -b1
)).str());
214 BOOST_CHECK_EQUAL(mpz_int(lcm(-c
, -d
)).str(), test_type(lcm(-c1
, -d1
)).str());
215 BOOST_CHECK_EQUAL(mpz_int(gcd(a
, -b
)).str(), test_type(gcd(a1
, -b1
)).str());
216 BOOST_CHECK_EQUAL(mpz_int(lcm(c
, -d
)).str(), test_type(lcm(c1
, -d1
)).str());
220 BOOST_CHECK_EQUAL(sqrt(a
, r
).str(), sqrt(a1
, r1
).str());
221 BOOST_CHECK_EQUAL(r
.str(), r1
.str());
226 using namespace boost::multiprecision
;
227 // Now check operations involving signed integers:
228 BOOST_CHECK_EQUAL(mpz_int(a
+ si
).str(), test_type(a1
+ si
).str());
229 BOOST_CHECK_EQUAL(mpz_int(a
+ -si
).str(), test_type(a1
+ -si
).str());
230 BOOST_CHECK_EQUAL(mpz_int(-a
+ si
).str(), test_type(-a1
+ si
).str());
231 BOOST_CHECK_EQUAL(mpz_int(si
+ a
).str(), test_type(si
+ a1
).str());
232 BOOST_CHECK_EQUAL((mpz_int(a
)+=si
).str(), (test_type(a1
) += si
).str());
233 BOOST_CHECK_EQUAL((mpz_int(a
)+=-si
).str(), (test_type(a1
) += -si
).str());
234 BOOST_CHECK_EQUAL((mpz_int(-a
)+=si
).str(), (test_type(-a1
) += si
).str());
235 BOOST_CHECK_EQUAL((mpz_int(-a
)+=-si
).str(), (test_type(-a1
) += -si
).str());
236 BOOST_CHECK_EQUAL(mpz_int(a
- si
).str(), test_type(a1
- si
).str());
237 BOOST_CHECK_EQUAL(mpz_int(a
- -si
).str(), test_type(a1
- -si
).str());
238 BOOST_CHECK_EQUAL(mpz_int(-a
- si
).str(), test_type(-a1
- si
).str());
239 BOOST_CHECK_EQUAL(mpz_int(si
- a
).str(), test_type(si
- a1
).str());
240 BOOST_CHECK_EQUAL((mpz_int(a
)-=si
).str(), (test_type(a1
) -= si
).str());
241 BOOST_CHECK_EQUAL((mpz_int(a
)-=-si
).str(), (test_type(a1
) -= -si
).str());
242 BOOST_CHECK_EQUAL((mpz_int(-a
)-=si
).str(), (test_type(-a1
) -= si
).str());
243 BOOST_CHECK_EQUAL((mpz_int(-a
)-=-si
).str(), (test_type(-a1
) -= -si
).str());
244 BOOST_CHECK_EQUAL(mpz_int(b
* si
).str(), test_type(b1
* si
).str());
245 BOOST_CHECK_EQUAL(mpz_int(b
* -si
).str(), test_type(b1
* -si
).str());
246 BOOST_CHECK_EQUAL(mpz_int(-b
* si
).str(), test_type(-b1
* si
).str());
247 BOOST_CHECK_EQUAL(mpz_int(si
* b
).str(), test_type(si
* b1
).str());
248 BOOST_CHECK_EQUAL((mpz_int(a
)*=si
).str(), (test_type(a1
) *= si
).str());
249 BOOST_CHECK_EQUAL((mpz_int(a
)*=-si
).str(), (test_type(a1
) *= -si
).str());
250 BOOST_CHECK_EQUAL((mpz_int(-a
)*=si
).str(), (test_type(-a1
) *= si
).str());
251 BOOST_CHECK_EQUAL((mpz_int(-a
)*=-si
).str(), (test_type(-a1
) *= -si
).str());
252 BOOST_CHECK_EQUAL(mpz_int(a
/ si
).str(), test_type(a1
/ si
).str());
253 BOOST_CHECK_EQUAL(mpz_int(a
/ -si
).str(), test_type(a1
/ -si
).str());
254 BOOST_CHECK_EQUAL(mpz_int(-a
/ si
).str(), test_type(-a1
/ si
).str());
255 BOOST_CHECK_EQUAL((mpz_int(a
)/=si
).str(), (test_type(a1
) /= si
).str());
256 BOOST_CHECK_EQUAL((mpz_int(a
)/=-si
).str(), (test_type(a1
) /= -si
).str());
257 BOOST_CHECK_EQUAL((mpz_int(-a
)/=si
).str(), (test_type(-a1
) /= si
).str());
258 BOOST_CHECK_EQUAL((mpz_int(-a
)/=-si
).str(), (test_type(-a1
) /= -si
).str());
259 BOOST_CHECK_EQUAL(mpz_int(a
% si
).str(), test_type(a1
% si
).str());
260 BOOST_CHECK_EQUAL(mpz_int(a
% -si
).str(), test_type(a1
% -si
).str());
261 BOOST_CHECK_EQUAL(mpz_int(-a
% si
).str(), test_type(-a1
% si
).str());
262 BOOST_CHECK_EQUAL((mpz_int(a
)%=si
).str(), (test_type(a1
) %= si
).str());
263 BOOST_CHECK_EQUAL((mpz_int(a
)%=-si
).str(), (test_type(a1
) %= -si
).str());
264 BOOST_CHECK_EQUAL((mpz_int(-a
)%=si
).str(), (test_type(-a1
) %= si
).str());
265 BOOST_CHECK_EQUAL((mpz_int(-a
)%=-si
).str(), (test_type(-a1
) %= -si
).str());
266 if((si
> 0) || !is_checked_cpp_int
<test_type
>::value
)
268 BOOST_CHECK_EQUAL(mpz_int(a
|si
).str(), test_type(a1
| si
).str());
269 BOOST_CHECK_EQUAL((mpz_int(a
)|=si
).str(), (test_type(a1
) |= si
).str());
270 BOOST_CHECK_EQUAL(mpz_int(a
&si
).str(), test_type(a1
& si
).str());
271 BOOST_CHECK_EQUAL((mpz_int(a
)&=si
).str(), (test_type(a1
) &= si
).str());
272 BOOST_CHECK_EQUAL(mpz_int(a
^si
).str(), test_type(a1
^ si
).str());
273 BOOST_CHECK_EQUAL((mpz_int(a
)^=si
).str(), (test_type(a1
) ^= si
).str());
274 BOOST_CHECK_EQUAL(mpz_int(si
|a
).str(), test_type(si
|a1
).str());
275 BOOST_CHECK_EQUAL(mpz_int(si
&a
).str(), test_type(si
&a1
).str());
276 BOOST_CHECK_EQUAL(mpz_int(si
^a
).str(), test_type(si
^a1
).str());
278 BOOST_CHECK_EQUAL(mpz_int(gcd(a
, si
)).str(), test_type(gcd(a1
, si
)).str());
279 BOOST_CHECK_EQUAL(mpz_int(gcd(si
, b
)).str(), test_type(gcd(si
, b1
)).str());
280 BOOST_CHECK_EQUAL(mpz_int(lcm(c
, si
)).str(), test_type(lcm(c1
, si
)).str());
281 BOOST_CHECK_EQUAL(mpz_int(lcm(si
, d
)).str(), test_type(lcm(si
, d1
)).str());
282 BOOST_CHECK_EQUAL(mpz_int(gcd(-a
, si
)).str(), test_type(gcd(-a1
, si
)).str());
283 BOOST_CHECK_EQUAL(mpz_int(gcd(-si
, b
)).str(), test_type(gcd(-si
, b1
)).str());
284 BOOST_CHECK_EQUAL(mpz_int(lcm(-c
, si
)).str(), test_type(lcm(-c1
, si
)).str());
285 BOOST_CHECK_EQUAL(mpz_int(lcm(-si
, d
)).str(), test_type(lcm(-si
, d1
)).str());
286 BOOST_CHECK_EQUAL(mpz_int(gcd(-a
, -si
)).str(), test_type(gcd(-a1
, -si
)).str());
287 BOOST_CHECK_EQUAL(mpz_int(gcd(-si
, -b
)).str(), test_type(gcd(-si
, -b1
)).str());
288 BOOST_CHECK_EQUAL(mpz_int(lcm(-c
, -si
)).str(), test_type(lcm(-c1
, -si
)).str());
289 BOOST_CHECK_EQUAL(mpz_int(lcm(-si
, -d
)).str(), test_type(lcm(-si
, -d1
)).str());
290 BOOST_CHECK_EQUAL(mpz_int(gcd(a
, -si
)).str(), test_type(gcd(a1
, -si
)).str());
291 BOOST_CHECK_EQUAL(mpz_int(gcd(si
, -b
)).str(), test_type(gcd(si
, -b1
)).str());
292 BOOST_CHECK_EQUAL(mpz_int(lcm(c
, -si
)).str(), test_type(lcm(c1
, -si
)).str());
293 BOOST_CHECK_EQUAL(mpz_int(lcm(si
, -d
)).str(), test_type(lcm(si
, -d1
)).str());
298 using namespace boost::multiprecision
;
299 // Now check operations involving unsigned integers:
300 BOOST_CHECK_EQUAL(mpz_int(a
+ ui
).str(), test_type(a1
+ ui
).str());
301 BOOST_CHECK_EQUAL(mpz_int(-a
+ ui
).str(), test_type(-a1
+ ui
).str());
302 BOOST_CHECK_EQUAL(mpz_int(ui
+ a
).str(), test_type(ui
+ a1
).str());
303 BOOST_CHECK_EQUAL((mpz_int(a
)+=ui
).str(), (test_type(a1
) += ui
).str());
304 BOOST_CHECK_EQUAL((mpz_int(-a
)+=ui
).str(), (test_type(-a1
) += ui
).str());
305 BOOST_CHECK_EQUAL(mpz_int(a
- ui
).str(), test_type(a1
- ui
).str());
306 BOOST_CHECK_EQUAL(mpz_int(-a
- ui
).str(), test_type(-a1
- ui
).str());
307 BOOST_CHECK_EQUAL(mpz_int(ui
- a
).str(), test_type(ui
- a1
).str());
308 BOOST_CHECK_EQUAL((mpz_int(a
)-=ui
).str(), (test_type(a1
) -= ui
).str());
309 BOOST_CHECK_EQUAL((mpz_int(-a
)-=ui
).str(), (test_type(-a1
) -= ui
).str());
310 BOOST_CHECK_EQUAL(mpz_int(b
* ui
).str(), test_type(b1
* ui
).str());
311 BOOST_CHECK_EQUAL(mpz_int(-b
* ui
).str(), test_type(-b1
* ui
).str());
312 BOOST_CHECK_EQUAL(mpz_int(ui
* b
).str(), test_type(ui
* b1
).str());
313 BOOST_CHECK_EQUAL((mpz_int(a
)*=ui
).str(), (test_type(a1
) *= ui
).str());
314 BOOST_CHECK_EQUAL((mpz_int(-a
)*=ui
).str(), (test_type(-a1
) *= ui
).str());
315 BOOST_CHECK_EQUAL(mpz_int(a
/ ui
).str(), test_type(a1
/ ui
).str());
316 BOOST_CHECK_EQUAL(mpz_int(-a
/ ui
).str(), test_type(-a1
/ ui
).str());
317 BOOST_CHECK_EQUAL((mpz_int(a
)/=ui
).str(), (test_type(a1
) /= ui
).str());
318 BOOST_CHECK_EQUAL((mpz_int(-a
)/=ui
).str(), (test_type(-a1
) /= ui
).str());
319 BOOST_CHECK_EQUAL(mpz_int(a
% ui
).str(), test_type(a1
% ui
).str());
320 BOOST_CHECK_EQUAL(mpz_int(-a
% ui
).str(), test_type(-a1
% ui
).str());
321 BOOST_CHECK_EQUAL((mpz_int(a
)%=ui
).str(), (test_type(a1
) %= ui
).str());
322 BOOST_CHECK_EQUAL((mpz_int(-a
)%=ui
).str(), (test_type(-a1
) %= ui
).str());
323 BOOST_CHECK_EQUAL(mpz_int(a
|ui
).str(), test_type(a1
| ui
).str());
324 BOOST_CHECK_EQUAL((mpz_int(a
)|=ui
).str(), (test_type(a1
) |= ui
).str());
325 BOOST_CHECK_EQUAL(mpz_int(a
&ui
).str(), test_type(a1
& ui
).str());
326 BOOST_CHECK_EQUAL((mpz_int(a
)&=ui
).str(), (test_type(a1
) &= ui
).str());
327 BOOST_CHECK_EQUAL(mpz_int(a
^ui
).str(), test_type(a1
^ ui
).str());
328 BOOST_CHECK_EQUAL((mpz_int(a
)^=ui
).str(), (test_type(a1
) ^= ui
).str());
329 BOOST_CHECK_EQUAL(mpz_int(ui
|a
).str(), test_type(ui
|a1
).str());
330 BOOST_CHECK_EQUAL(mpz_int(ui
&a
).str(), test_type(ui
&a1
).str());
331 BOOST_CHECK_EQUAL(mpz_int(ui
^a
).str(), test_type(ui
^a1
).str());
332 BOOST_CHECK_EQUAL(mpz_int(gcd(a
, ui
)).str(), test_type(gcd(a1
, ui
)).str());
333 BOOST_CHECK_EQUAL(mpz_int(gcd(ui
, b
)).str(), test_type(gcd(ui
, b1
)).str());
334 BOOST_CHECK_EQUAL(mpz_int(lcm(c
, ui
)).str(), test_type(lcm(c1
, ui
)).str());
335 BOOST_CHECK_EQUAL(mpz_int(lcm(ui
, d
)).str(), test_type(lcm(ui
, d1
)).str());
336 BOOST_CHECK_EQUAL(mpz_int(gcd(-a
, ui
)).str(), test_type(gcd(-a1
, ui
)).str());
337 BOOST_CHECK_EQUAL(mpz_int(lcm(-c
, ui
)).str(), test_type(lcm(-c1
, ui
)).str());
338 BOOST_CHECK_EQUAL(mpz_int(gcd(ui
, -b
)).str(), test_type(gcd(ui
, -b1
)).str());
339 BOOST_CHECK_EQUAL(mpz_int(lcm(ui
, -d
)).str(), test_type(lcm(ui
, -d1
)).str());
341 if(std::numeric_limits
<test_type
>::is_modulo
&& checked::value
)
343 static mpz_int m
= mpz_int(1) << std::numeric_limits
<test_type
>::digits
;
346 for(unsigned i
= 0; i
< 10; ++i
)
355 BOOST_CHECK_EQUAL(t
.str(), t1
.str());
361 using namespace boost::multiprecision
;
363 // Now integer functions:
367 divide_qr(a
, b
, z1
, z2
);
368 divide_qr(a1
, b1
, t1
, t2
);
369 BOOST_CHECK_EQUAL(z1
.str(), t1
.str());
370 BOOST_CHECK_EQUAL(z2
.str(), t2
.str());
371 BOOST_CHECK_EQUAL(integer_modulus(a
, si
), integer_modulus(a1
, si
));
372 BOOST_CHECK_EQUAL(lsb(a
), lsb(a1
));
373 BOOST_CHECK_EQUAL(msb(a
), msb(a1
));
375 for(unsigned i
= 0; i
< 1000; i
+= 13)
377 BOOST_CHECK_EQUAL(bit_test(a
, i
), bit_test(a1
, i
));
379 if(!std::numeric_limits
<test_type
>::is_modulo
)
381 // We have to take care that our powers don't grow too large, otherwise this takes "forever",
382 // also don't test for modulo types, as these may give a different result from arbitrary
384 BOOST_CHECK_EQUAL(mpz_int(pow(d
, ui
% 19)).str(), test_type(pow(d1
, ui
% 19)).str());
385 BOOST_CHECK_EQUAL(mpz_int(powm(a
, b
, c
)).str(), test_type(powm(a1
, b1
, c1
)).str());
386 BOOST_CHECK_EQUAL(mpz_int(powm(a
, b
, ui
)).str(), test_type(powm(a1
, b1
, ui
)).str());
387 BOOST_CHECK_EQUAL(mpz_int(powm(a
, ui
, c
)).str(), test_type(powm(a1
, ui
, c1
)).str());
389 BOOST_CHECK_EQUAL(lsb(a
), lsb(a1
));
390 BOOST_CHECK_EQUAL(msb(a
), msb(a1
));
393 static void test_bug_cases()
395 if(!std::numeric_limits
<test_type
>::is_bounded
)
397 // https://svn.boost.org/trac/boost/ticket/7878
398 test_type
a("0x1000000000000000000000000000000000000000000000000000000000000000");
399 test_type b
= 0xFFFFFFFF;
400 test_type c
= a
* b
+ b
; // quotient has 1 in the final place
402 divide_qr(c
, b
, q
, r
);
403 BOOST_CHECK_EQUAL(a
+ 1, q
);
404 BOOST_CHECK_EQUAL(r
, 0);
406 b
= static_cast<test_type
>("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
407 c
= a
* b
+ b
; // quotient has 1 in the final place
408 divide_qr(c
, b
, q
, r
);
409 BOOST_CHECK_EQUAL(a
+ 1, q
);
410 BOOST_CHECK_EQUAL(r
, 0);
412 // Not a bug, but test some other special cases that don't otherwise occur through
415 c
= a
* b
; // quotient has zero in the final place
416 divide_qr(c
, b
, q
, r
);
417 BOOST_CHECK_EQUAL(q
, a
);
418 BOOST_CHECK_EQUAL(r
, 0);
419 divide_qr(c
, a
, q
, r
);
420 BOOST_CHECK_EQUAL(q
, b
);
421 BOOST_CHECK_EQUAL(r
, 0);
423 divide_qr(c
, b
, q
, r
);
424 BOOST_CHECK_EQUAL(q
, a
);
425 BOOST_CHECK_EQUAL(r
, 1);
427 // Bug https://svn.boost.org/trac/boost/ticket/8126:
428 test_type
a("-4294967296");
429 test_type
b("4294967296");
432 BOOST_CHECK_EQUAL(a
, -1);
435 BOOST_CHECK_EQUAL(a
, 1);
439 BOOST_CHECK_EQUAL(a
, 1);
442 BOOST_CHECK_EQUAL(a
, 1);
443 a
= test_type("-26607734784073568386365259775");
444 b
= test_type("8589934592");
446 BOOST_CHECK_EQUAL(a
, test_type("-3097548007973652377"));
447 // Bug https://svn.boost.org/trac/boost/ticket/8133:
448 a
= test_type("0x12345600012434ffffffffffffffffffffffff");
449 unsigned ui
= 0xffffffff;
451 BOOST_CHECK_EQUAL(a
, test_type("0x12345600012434ffffffffffffffff00000000"));
452 a
= test_type("0x12345600012434ffffffffffffffffffffffff");
453 #ifndef BOOST_NO_LONG_LONG
454 unsigned long long ull
= 0xffffffffffffffffuLL
;
456 BOOST_CHECK_EQUAL(a
, test_type("0x12345600012434ffffffff0000000000000000"));
459 // Now check that things which should be zero really are
460 // https://svn.boost.org/trac/boost/ticket/8145:
464 BOOST_CHECK_EQUAL(a
, 0);
467 BOOST_CHECK_EQUAL(a
, 0);
470 BOOST_CHECK_EQUAL(a
, 0);
473 BOOST_CHECK_EQUAL(a
, 0);
474 a
= test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
475 a
-= test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
476 BOOST_CHECK_EQUAL(a
, 0);
477 a
= -test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
478 a
+= test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
479 BOOST_CHECK_EQUAL(a
, 0);
482 BOOST_CHECK_EQUAL(a
, 0);
485 BOOST_CHECK_EQUAL(a
, 0);
488 BOOST_CHECK_EQUAL(a
, 0);
491 BOOST_CHECK_EQUAL(a
, 0);
494 BOOST_CHECK_EQUAL(a
, 0);
495 a
= -test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
496 a
/= (1 + test_type("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
497 BOOST_CHECK_EQUAL(a
, 0);
498 // https://svn.boost.org/trac/boost/ticket/8160
500 a
= 0 / test_type(1);
501 BOOST_CHECK_EQUAL(a
, 0);
503 a
= 0 % test_type(25);
504 BOOST_CHECK_EQUAL(a
, 0);
506 // https://svn.boost.org/trac/boost/ticket/11364
510 test_type d
= ~(a
^ ~b
);
511 BOOST_CHECK_EQUAL(c
, d
);
513 #if defined(TEST2) || defined(TEST3)
514 // https://svn.boost.org/trac/boost/ticket/11648
515 a
= (std::numeric_limits
<test_type
>::max
)() - 69;
521 BOOST_CHECK_EQUAL(a
- c
* b
, r
);
523 for(ui
= 0; ui
< 1000; ++ui
)
525 boost::multiprecision::mpz_int t
;
526 boost::multiprecision::mpz_int s1
= sqrt(boost::multiprecision::mpz_int(ui
), t
);
527 a
= sqrt(test_type(ui
), b
);
528 BOOST_CHECK_EQUAL(a
.str(), s1
.str());
529 BOOST_CHECK_EQUAL(b
.str(), t
.str());
535 using namespace boost::multiprecision
;
539 last_error_count
= 0;
541 BOOST_CHECK_EQUAL(Number(), 0);
543 for(int i
= 0; i
< 10000; ++i
)
545 a
= generate_random
<mpz_int
>(1000);
546 b
= generate_random
<mpz_int
>(512);
547 c
= generate_random
<mpz_int
>(256);
548 d
= generate_random
<mpz_int
>(32);
550 si
= d
.convert_to
<int>();
553 a1
= static_cast<test_type
>(a
.str());
554 b1
= static_cast<test_type
>(b
.str());
555 c1
= static_cast<test_type
>(c
.str());
556 d1
= static_cast<test_type
>(d
.str());
560 #ifndef SLOW_COMPILER
566 if(last_error_count
!= (unsigned)boost::detail::test_errors())
568 last_error_count
= boost::detail::test_errors();
569 std::cout
<< std::hex
<< std::showbase
;
571 std::cout
<< "a = " << a
<< std::endl
;
572 std::cout
<< "a1 = " << a1
<< std::endl
;
573 std::cout
<< "b = " << b
<< std::endl
;
574 std::cout
<< "b1 = " << b1
<< std::endl
;
575 std::cout
<< "c = " << c
<< std::endl
;
576 std::cout
<< "c1 = " << c1
<< std::endl
;
577 std::cout
<< "d = " << d
<< std::endl
;
578 std::cout
<< "d1 = " << d1
<< std::endl
;
579 std::cout
<< "a + b = " << a
+b
<< std::endl
;
580 std::cout
<< "a1 + b1 = " << a1
+b1
<< std::endl
;
581 std::cout
<< std::dec
;
582 std::cout
<< "a - b = " << a
-b
<< std::endl
;
583 std::cout
<< "a1 - b1 = " << a1
-b1
<< std::endl
;
584 std::cout
<< "-a + b = " << mpz_int(-a
)+b
<< std::endl
;
585 std::cout
<< "-a1 + b1 = " << test_type(-a1
)+b1
<< std::endl
;
586 std::cout
<< "-a - b = " << mpz_int(-a
)-b
<< std::endl
;
587 std::cout
<< "-a1 - b1 = " << test_type(-a1
)-b1
<< std::endl
;
588 std::cout
<< "c*d = " << c
*d
<< std::endl
;
589 std::cout
<< "c1*d1 = " << c1
*d1
<< std::endl
;
590 std::cout
<< "b*c = " << b
*c
<< std::endl
;
591 std::cout
<< "b1*c1 = " << b1
*c1
<< std::endl
;
592 std::cout
<< "a/b = " << a
/b
<< std::endl
;
593 std::cout
<< "a1/b1 = " << a1
/b1
<< std::endl
;
594 std::cout
<< "a/d = " << a
/d
<< std::endl
;
595 std::cout
<< "a1/d1 = " << a1
/d1
<< std::endl
;
596 std::cout
<< "a%b = " << a
%b
<< std::endl
;
597 std::cout
<< "a1%b1 = " << a1
%b1
<< std::endl
;
598 std::cout
<< "a%d = " << a
%d
<< std::endl
;
599 std::cout
<< "a1%d1 = " << a1
%d1
<< std::endl
;
603 // Check to see if test is taking too long.
604 // Tests run on the compiler farm time out after 300 seconds,
605 // so don't get too close to that:
607 #ifndef CI_SUPPRESS_KNOWN_ISSUES
608 if(tim
.elapsed() > 200)
610 if (tim
.elapsed() > 25)
613 std::cout
<< "Timeout reached, aborting tests now....\n";
623 using namespace boost::multiprecision
;
630 tester
<number
<cpp_int_backend
<2048, 2048, signed_magnitude
, checked
, void> > > t2
;
634 // Unchecked test verifies modulo arithmetic:
635 tester
<number
<cpp_int_backend
<2048, 2048, signed_magnitude
, unchecked
, void> > > t3
;
639 tester
<number
<cpp_int_backend
<0, 2048, signed_magnitude
, unchecked
, std::allocator
<void> > > > t4
;
643 tester
<number
<cpp_int_backend
<0, 2048, signed_magnitude
, unchecked
> > > t5
;
646 return boost::report_errors();