]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/math/test/common_factor_test.cpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / math / test / common_factor_test.cpp
CommitLineData
7c673cae
FG
1// Boost GCD & LCM common_factor.hpp test program --------------------------//
2
3// (C) Copyright Daryle Walker 2001, 2006.
4// Distributed under the Boost Software License, Version 1.0. (See
5// accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7
8// See http://www.boost.org for most recent version including documentation.
9
10// Revision History
11// 01 Dec 2006 Various fixes for old compilers (Joaquin M Lopez Munoz)
12// 10 Nov 2006 Make long long and __int64 mutually exclusive (Daryle Walker)
13// 04 Nov 2006 Use more built-in numeric types, binary-GCD (Daryle Walker)
14// 03 Nov 2006 Use custom numeric types (Daryle Walker)
15// 02 Nov 2006 Change to Boost.Test's unit test system (Daryle Walker)
16// 07 Nov 2001 Initial version (Daryle Walker)
17
18#define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests"
19
20#include <boost/config.hpp> // for BOOST_MSVC, etc.
21#include <boost/detail/workaround.hpp>
22#include <boost/math/common_factor.hpp> // for boost::math::gcd, etc.
23#include <boost/mpl/list.hpp> // for boost::mpl::list
24#include <boost/operators.hpp>
25#include <boost/test/unit_test.hpp>
26
27#include <istream> // for std::basic_istream
28#include <limits> // for std::numeric_limits
29#include <ostream> // for std::basic_ostream
30
31
32namespace {
33
34// TODO: add polynominal/non-real type; especially after any switch to the
35// binary-GCD algorithm for built-in types
36
37// Custom integer class (template)
38template < typename IntType, int ID = 0 >
39class my_wrapped_integer
40 : private ::boost::shiftable1<my_wrapped_integer<IntType, ID>,
41 ::boost::operators<my_wrapped_integer<IntType, ID> > >
42{
43 // Helper type-aliases
44 typedef my_wrapped_integer self_type;
45 typedef IntType self_type::* bool_type;
46
47 // Member data
48 IntType v_;
49
50public:
51 // Template parameters
52 typedef IntType int_type;
53
54 BOOST_STATIC_CONSTANT(int,id = ID);
55
56 // Lifetime management (use automatic destructor and copy constructor)
57 my_wrapped_integer( int_type const &v = int_type() ) : v_( v ) {}
58
59 // Accessors
60 int_type value() const { return this->v_; }
61
62 // Operators (use automatic copy assignment)
63 operator bool_type() const { return this->v_ ? &self_type::v_ : 0; }
64
65 self_type & operator ++() { ++this->v_; return *this; }
66 self_type & operator --() { --this->v_; return *this; }
67
68 self_type operator ~() const { return self_type( ~this->v_ ); }
69 self_type operator !() const { return self_type( !this->v_ ); }
70 self_type operator +() const { return self_type( +this->v_ ); }
71 self_type operator -() const { return self_type( -this->v_ ); }
72
73 bool operator <( self_type const &r ) const { return this->v_ < r.v_; }
74 bool operator ==( self_type const &r ) const { return this->v_ == r.v_; }
75
76 self_type &operator *=(self_type const &r) {this->v_ *= r.v_; return *this;}
77 self_type &operator /=(self_type const &r) {this->v_ /= r.v_; return *this;}
78 self_type &operator %=(self_type const &r) {this->v_ %= r.v_; return *this;}
79 self_type &operator +=(self_type const &r) {this->v_ += r.v_; return *this;}
80 self_type &operator -=(self_type const &r) {this->v_ -= r.v_; return *this;}
81 self_type &operator<<=(self_type const &r){this->v_ <<= r.v_; return *this;}
82 self_type &operator>>=(self_type const &r){this->v_ >>= r.v_; return *this;}
83 self_type &operator &=(self_type const &r) {this->v_ &= r.v_; return *this;}
84 self_type &operator |=(self_type const &r) {this->v_ |= r.v_; return *this;}
85 self_type &operator ^=(self_type const &r) {this->v_ ^= r.v_; return *this;}
86
87 // Input & output
88 friend std::istream & operator >>( std::istream &i, self_type &x )
89 { return i >> x.v_; }
90
91 friend std::ostream & operator <<( std::ostream &o, self_type const &x )
92 { return o << x.v_; }
93
94}; // my_wrapped_integer
95
96template < typename IntType, int ID >
97my_wrapped_integer<IntType, ID> abs( my_wrapped_integer<IntType, ID> const &x )
98{ return ( x < my_wrapped_integer<IntType, ID>(0) ) ? -x : +x; }
99
100typedef my_wrapped_integer<int> MyInt1;
101typedef my_wrapped_integer<unsigned> MyUnsigned1;
102typedef my_wrapped_integer<int, 1> MyInt2;
103typedef my_wrapped_integer<unsigned, 1> MyUnsigned2;
104
105// Without these explicit instantiations, MSVC++ 6.5/7.0 does not find
106// some friend operators in certain contexts.
107MyInt1 dummy1;
108MyUnsigned1 dummy2;
109MyInt2 dummy3;
110MyUnsigned2 dummy4;
111
112// Various types to test with each GCD/LCM
113typedef ::boost::mpl::list<signed char, short, int, long,
114#if BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
115#elif defined(BOOST_HAS_LONG_LONG)
116 boost::long_long_type,
117#elif defined(BOOST_HAS_MS_INT64)
118 __int64,
119#endif
120 MyInt1> signed_test_types;
121typedef ::boost::mpl::list<unsigned char, unsigned short, unsigned,
122 unsigned long,
123#if BOOST_WORKAROUND(BOOST_MSVC, <= 1500)
124#elif defined(BOOST_HAS_LONG_LONG)
125 boost::ulong_long_type,
126#elif defined(BOOST_HAS_MS_INT64)
127 unsigned __int64,
128#endif
129 MyUnsigned1, MyUnsigned2> unsigned_test_types;
130
131} // namespace
132
133#define BOOST_NO_MACRO_EXPAND /**/
134
135// Specialize numeric_limits for _some_ of our types
136namespace std
137{
138
139template < >
140class numeric_limits< MyInt1 >
141{
142 typedef MyInt1::int_type int_type;
143 typedef numeric_limits<int_type> limits_type;
144
145public:
146 BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized);
147
148 static MyInt1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); }
149 static MyInt1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); }
150
151 BOOST_STATIC_CONSTANT(int, digits = limits_type::digits);
152 BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10);
153#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
154 BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10);
155#endif
156 BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed);
157 BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer);
158 BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact);
159 BOOST_STATIC_CONSTANT(int, radix = limits_type::radix);
160 static MyInt1 epsilon() throw() { return limits_type::epsilon(); }
161 static MyInt1 round_error() throw() { return limits_type::round_error(); }
162
163 BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent);
164 BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10);
165 BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent);
166 BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10);
167
168 BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity);
169 BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN);
170 BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN);
171 BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm);
172 BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss);
173
174 static MyInt1 infinity() throw() { return limits_type::infinity(); }
175 static MyInt1 quiet_NaN() throw() { return limits_type::quiet_NaN(); }
176 static MyInt1 signaling_NaN() throw() {return limits_type::signaling_NaN();}
177 static MyInt1 denorm_min() throw() { return limits_type::denorm_min(); }
178
179 BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559);
180 BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded);
181 BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo);
182
183 BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps);
184 BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before);
185 BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style);
186
187}; // std::numeric_limits<MyInt1>
188
189template < >
190class numeric_limits< MyUnsigned1 >
191{
192 typedef MyUnsigned1::int_type int_type;
193 typedef numeric_limits<int_type> limits_type;
194
195public:
196 BOOST_STATIC_CONSTANT(bool, is_specialized = limits_type::is_specialized);
197
198 static MyUnsigned1 min BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::min)(); }
199 static MyUnsigned1 max BOOST_NO_MACRO_EXPAND() throw() { return (limits_type::max)(); }
200
201 BOOST_STATIC_CONSTANT(int, digits = limits_type::digits);
202 BOOST_STATIC_CONSTANT(int, digits10 = limits_type::digits10);
203#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS
204 BOOST_STATIC_CONSTANT(int, max_digits10 = limits_type::max_digits10);
205#endif
206 BOOST_STATIC_CONSTANT(bool, is_signed = limits_type::is_signed);
207 BOOST_STATIC_CONSTANT(bool, is_integer = limits_type::is_integer);
208 BOOST_STATIC_CONSTANT(bool, is_exact = limits_type::is_exact);
209 BOOST_STATIC_CONSTANT(int, radix = limits_type::radix);
210 static MyUnsigned1 epsilon() throw() { return limits_type::epsilon(); }
211 static MyUnsigned1 round_error() throw(){return limits_type::round_error();}
212
213 BOOST_STATIC_CONSTANT(int, min_exponent = limits_type::min_exponent);
214 BOOST_STATIC_CONSTANT(int, min_exponent10 = limits_type::min_exponent10);
215 BOOST_STATIC_CONSTANT(int, max_exponent = limits_type::max_exponent);
216 BOOST_STATIC_CONSTANT(int, max_exponent10 = limits_type::max_exponent10);
217
218 BOOST_STATIC_CONSTANT(bool, has_infinity = limits_type::has_infinity);
219 BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = limits_type::has_quiet_NaN);
220 BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = limits_type::has_signaling_NaN);
221 BOOST_STATIC_CONSTANT(float_denorm_style, has_denorm = limits_type::has_denorm);
222 BOOST_STATIC_CONSTANT(bool, has_denorm_loss = limits_type::has_denorm_loss);
223
224 static MyUnsigned1 infinity() throw() { return limits_type::infinity(); }
225 static MyUnsigned1 quiet_NaN() throw() { return limits_type::quiet_NaN(); }
226 static MyUnsigned1 signaling_NaN() throw()
227 { return limits_type::signaling_NaN(); }
228 static MyUnsigned1 denorm_min() throw(){ return limits_type::denorm_min(); }
229
230 BOOST_STATIC_CONSTANT(bool, is_iec559 = limits_type::is_iec559);
231 BOOST_STATIC_CONSTANT(bool, is_bounded = limits_type::is_bounded);
232 BOOST_STATIC_CONSTANT(bool, is_modulo = limits_type::is_modulo);
233
234 BOOST_STATIC_CONSTANT(bool, traps = limits_type::traps);
235 BOOST_STATIC_CONSTANT(bool, tinyness_before = limits_type::tinyness_before);
236 BOOST_STATIC_CONSTANT(float_round_style, round_style = limits_type::round_style);
237
238}; // std::numeric_limits<MyUnsigned1>
239
240#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
241// MSVC 6.0 lacks operator<< for __int64, see
242// http://support.microsoft.com/default.aspx?scid=kb;en-us;168440
243
244inline ostream& operator<<(ostream& os, __int64 i)
245{
246 char buf[20];
247 sprintf(buf,"%I64d", i);
248 os << buf;
249 return os;
250}
251
252inline ostream& operator<<(ostream& os, unsigned __int64 i)
253{
254 char buf[20];
255 sprintf(buf,"%I64u", i);
256 os << buf;
257 return os;
258}
259#endif
260
261} // namespace std
262
263// GCD tests
264BOOST_AUTO_TEST_SUITE( gcd_test_suite )
265
266// GCD on signed integer types
267BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test, T, signed_test_types )
268{
269#ifndef BOOST_MSVC
270 using boost::math::gcd;
271#else
272 using namespace boost::math;
273#endif
274
275 // Originally from Boost.Rational tests
276 BOOST_CHECK_EQUAL( gcd<T>( 1, -1), static_cast<T>( 1) );
277 BOOST_CHECK_EQUAL( gcd<T>( -1, 1), static_cast<T>( 1) );
278 BOOST_CHECK_EQUAL( gcd<T>( 1, 1), static_cast<T>( 1) );
279 BOOST_CHECK_EQUAL( gcd<T>( -1, -1), static_cast<T>( 1) );
280 BOOST_CHECK_EQUAL( gcd<T>( 0, 0), static_cast<T>( 0) );
281 BOOST_CHECK_EQUAL( gcd<T>( 7, 0), static_cast<T>( 7) );
282 BOOST_CHECK_EQUAL( gcd<T>( 0, 9), static_cast<T>( 9) );
283 BOOST_CHECK_EQUAL( gcd<T>( -7, 0), static_cast<T>( 7) );
284 BOOST_CHECK_EQUAL( gcd<T>( 0, -9), static_cast<T>( 9) );
285 BOOST_CHECK_EQUAL( gcd<T>( 42, 30), static_cast<T>( 6) );
286 BOOST_CHECK_EQUAL( gcd<T>( 6, -9), static_cast<T>( 3) );
287 BOOST_CHECK_EQUAL( gcd<T>(-10, -10), static_cast<T>(10) );
288 BOOST_CHECK_EQUAL( gcd<T>(-25, -10), static_cast<T>( 5) );
289 BOOST_CHECK_EQUAL( gcd<T>( 3, 7), static_cast<T>( 1) );
290 BOOST_CHECK_EQUAL( gcd<T>( 8, 9), static_cast<T>( 1) );
291 BOOST_CHECK_EQUAL( gcd<T>( 7, 49), static_cast<T>( 7) );
292}
293
294// GCD on unmarked signed integer type
295BOOST_AUTO_TEST_CASE( gcd_unmarked_int_test )
296{
297#ifndef BOOST_MSVC
298 using boost::math::gcd;
299#else
300 using namespace boost::math;
301#endif
302
303 // The regular signed-integer GCD function performs the unsigned version,
304 // then does an absolute-value on the result. Signed types that are not
305 // marked as such (due to no std::numeric_limits specialization) may be off
306 // by a sign.
307 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 1, -1 )), MyInt2( 1) );
308 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( -1, 1 )), MyInt2( 1) );
309 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 1, 1 )), MyInt2( 1) );
310 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( -1, -1 )), MyInt2( 1) );
311 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 0, 0 )), MyInt2( 0) );
312 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 7, 0 )), MyInt2( 7) );
313 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 0, 9 )), MyInt2( 9) );
314 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( -7, 0 )), MyInt2( 7) );
315 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 0, -9 )), MyInt2( 9) );
316 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 42, 30 )), MyInt2( 6) );
317 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 6, -9 )), MyInt2( 3) );
318 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( -10, -10 )), MyInt2(10) );
319 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( -25, -10 )), MyInt2( 5) );
320 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 3, 7 )), MyInt2( 1) );
321 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 8, 9 )), MyInt2( 1) );
322 BOOST_CHECK_EQUAL( abs(gcd<MyInt2>( 7, 49 )), MyInt2( 7) );
323}
324
325// GCD on unsigned integer types
326BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_unsigned_test, T, unsigned_test_types )
327{
328#ifndef BOOST_MSVC
329 using boost::math::gcd;
330#else
331 using namespace boost::math;
332#endif
333
334 // Note that unmarked types (i.e. have no std::numeric_limits
335 // specialization) are treated like non/unsigned types
336 BOOST_CHECK_EQUAL( gcd<T>( 1u, 1u), static_cast<T>( 1u) );
337 BOOST_CHECK_EQUAL( gcd<T>( 0u, 0u), static_cast<T>( 0u) );
338 BOOST_CHECK_EQUAL( gcd<T>( 7u, 0u), static_cast<T>( 7u) );
339 BOOST_CHECK_EQUAL( gcd<T>( 0u, 9u), static_cast<T>( 9u) );
340 BOOST_CHECK_EQUAL( gcd<T>(42u, 30u), static_cast<T>( 6u) );
341 BOOST_CHECK_EQUAL( gcd<T>( 3u, 7u), static_cast<T>( 1u) );
342 BOOST_CHECK_EQUAL( gcd<T>( 8u, 9u), static_cast<T>( 1u) );
343 BOOST_CHECK_EQUAL( gcd<T>( 7u, 49u), static_cast<T>( 7u) );
344}
345
346// GCD at compile-time
347BOOST_AUTO_TEST_CASE( gcd_static_test )
348{
349#ifndef BOOST_MSVC
350 using boost::math::static_gcd;
351#else
352 using namespace boost::math;
353#endif
354
355 // Can't use "BOOST_CHECK_EQUAL", otherwise the "value" member will be
356 // disqualified as compile-time-only constant, needing explicit definition
357 BOOST_CHECK( (static_gcd< 1, 1>::value) == 1 );
358 BOOST_CHECK( (static_gcd< 0, 0>::value) == 0 );
359 BOOST_CHECK( (static_gcd< 7, 0>::value) == 7 );
360 BOOST_CHECK( (static_gcd< 0, 9>::value) == 9 );
361 BOOST_CHECK( (static_gcd<42, 30>::value) == 6 );
362 BOOST_CHECK( (static_gcd< 3, 7>::value) == 1 );
363 BOOST_CHECK( (static_gcd< 8, 9>::value) == 1 );
364 BOOST_CHECK( (static_gcd< 7, 49>::value) == 7 );
365}
366
367// TODO: non-built-in signed and unsigned integer tests, with and without
368// numeric_limits specialization; polynominal tests; note any changes if
369// built-ins switch to binary-GCD algorithm
370
371BOOST_AUTO_TEST_SUITE_END()
372
373
374// LCM tests
375BOOST_AUTO_TEST_SUITE( lcm_test_suite )
376
377// LCM on signed integer types
378BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test, T, signed_test_types )
379{
380#ifndef BOOST_MSVC
381 using boost::math::lcm;
382#else
383 using namespace boost::math;
384#endif
385
386 // Originally from Boost.Rational tests
387 BOOST_CHECK_EQUAL( lcm<T>( 1, -1), static_cast<T>( 1) );
388 BOOST_CHECK_EQUAL( lcm<T>( -1, 1), static_cast<T>( 1) );
389 BOOST_CHECK_EQUAL( lcm<T>( 1, 1), static_cast<T>( 1) );
390 BOOST_CHECK_EQUAL( lcm<T>( -1, -1), static_cast<T>( 1) );
391 BOOST_CHECK_EQUAL( lcm<T>( 0, 0), static_cast<T>( 0) );
392 BOOST_CHECK_EQUAL( lcm<T>( 6, 0), static_cast<T>( 0) );
393 BOOST_CHECK_EQUAL( lcm<T>( 0, 7), static_cast<T>( 0) );
394 BOOST_CHECK_EQUAL( lcm<T>( -5, 0), static_cast<T>( 0) );
395 BOOST_CHECK_EQUAL( lcm<T>( 0, -4), static_cast<T>( 0) );
396 BOOST_CHECK_EQUAL( lcm<T>( 18, 30), static_cast<T>(90) );
397 BOOST_CHECK_EQUAL( lcm<T>( -6, 9), static_cast<T>(18) );
398 BOOST_CHECK_EQUAL( lcm<T>(-10, -10), static_cast<T>(10) );
399 BOOST_CHECK_EQUAL( lcm<T>( 25, -10), static_cast<T>(50) );
400 BOOST_CHECK_EQUAL( lcm<T>( 3, 7), static_cast<T>(21) );
401 BOOST_CHECK_EQUAL( lcm<T>( 8, 9), static_cast<T>(72) );
402 BOOST_CHECK_EQUAL( lcm<T>( 7, 49), static_cast<T>(49) );
403}
404
405// LCM on unmarked signed integer type
406BOOST_AUTO_TEST_CASE( lcm_unmarked_int_test )
407{
408#ifndef BOOST_MSVC
409 using boost::math::lcm;
410#else
411 using namespace boost::math;
412#endif
413
414 // The regular signed-integer LCM function performs the unsigned version,
415 // then does an absolute-value on the result. Signed types that are not
416 // marked as such (due to no std::numeric_limits specialization) may be off
417 // by a sign.
418 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 1, -1 )), MyInt2( 1) );
419 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( -1, 1 )), MyInt2( 1) );
420 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 1, 1 )), MyInt2( 1) );
421 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( -1, -1 )), MyInt2( 1) );
422 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 0, 0 )), MyInt2( 0) );
423 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 6, 0 )), MyInt2( 0) );
424 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 0, 7 )), MyInt2( 0) );
425 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( -5, 0 )), MyInt2( 0) );
426 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 0, -4 )), MyInt2( 0) );
427 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 18, 30 )), MyInt2(90) );
428 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( -6, 9 )), MyInt2(18) );
429 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( -10, -10 )), MyInt2(10) );
430 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 25, -10 )), MyInt2(50) );
431 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 3, 7 )), MyInt2(21) );
432 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 8, 9 )), MyInt2(72) );
433 BOOST_CHECK_EQUAL( abs(lcm<MyInt2>( 7, 49 )), MyInt2(49) );
434}
435
436// LCM on unsigned integer types
437BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_unsigned_test, T, unsigned_test_types )
438{
439#ifndef BOOST_MSVC
440 using boost::math::lcm;
441#else
442 using namespace boost::math;
443#endif
444
445 // Note that unmarked types (i.e. have no std::numeric_limits
446 // specialization) are treated like non/unsigned types
447 BOOST_CHECK_EQUAL( lcm<T>( 1u, 1u), static_cast<T>( 1u) );
448 BOOST_CHECK_EQUAL( lcm<T>( 0u, 0u), static_cast<T>( 0u) );
449 BOOST_CHECK_EQUAL( lcm<T>( 6u, 0u), static_cast<T>( 0u) );
450 BOOST_CHECK_EQUAL( lcm<T>( 0u, 7u), static_cast<T>( 0u) );
451 BOOST_CHECK_EQUAL( lcm<T>(18u, 30u), static_cast<T>(90u) );
452 BOOST_CHECK_EQUAL( lcm<T>( 3u, 7u), static_cast<T>(21u) );
453 BOOST_CHECK_EQUAL( lcm<T>( 8u, 9u), static_cast<T>(72u) );
454 BOOST_CHECK_EQUAL( lcm<T>( 7u, 49u), static_cast<T>(49u) );
455}
456
457// LCM at compile-time
458BOOST_AUTO_TEST_CASE( lcm_static_test )
459{
460#ifndef BOOST_MSVC
461 using boost::math::static_lcm;
462#else
463 using namespace boost::math;
464#endif
465
466 // Can't use "BOOST_CHECK_EQUAL", otherwise the "value" member will be
467 // disqualified as compile-time-only constant, needing explicit definition
468 BOOST_CHECK( (static_lcm< 1, 1>::value) == 1 );
469 BOOST_CHECK( (static_lcm< 0, 0>::value) == 0 );
470 BOOST_CHECK( (static_lcm< 6, 0>::value) == 0 );
471 BOOST_CHECK( (static_lcm< 0, 7>::value) == 0 );
472 BOOST_CHECK( (static_lcm<18, 30>::value) == 90 );
473 BOOST_CHECK( (static_lcm< 3, 7>::value) == 21 );
474 BOOST_CHECK( (static_lcm< 8, 9>::value) == 72 );
475 BOOST_CHECK( (static_lcm< 7, 49>::value) == 49 );
476}
477
478// TODO: see GCD to-do
479
480BOOST_AUTO_TEST_SUITE_END()