1 // Boost GCD & LCM common_factor.hpp test program --------------------------//
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)
8 // See http://www.boost.org for most recent version including documentation.
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)
18 #define BOOST_TEST_MAIN "Boost.Math GCD & LCM unit tests"
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>
27 #include <istream> // for std::basic_istream
28 #include <limits> // for std::numeric_limits
29 #include <ostream> // for std::basic_ostream
34 // TODO: add polynominal/non-real type; especially after any switch to the
35 // binary-GCD algorithm for built-in types
37 // Custom integer class (template)
38 template < typename IntType
, int ID
= 0 >
39 class my_wrapped_integer
40 : private ::boost::shiftable1
<my_wrapped_integer
<IntType
, ID
>,
41 ::boost::operators
<my_wrapped_integer
<IntType
, ID
> > >
43 // Helper type-aliases
44 typedef my_wrapped_integer self_type
;
45 typedef IntType
self_type::* bool_type
;
51 // Template parameters
52 typedef IntType int_type
;
54 BOOST_STATIC_CONSTANT(int,id
= ID
);
56 // Lifetime management (use automatic destructor and copy constructor)
57 my_wrapped_integer( int_type
const &v
= int_type() ) : v_( v
) {}
60 int_type
value() const { return this->v_
; }
62 // Operators (use automatic copy assignment)
63 operator bool_type() const { return this->v_
? &self_type::v_
: 0; }
65 self_type
& operator ++() { ++this->v_
; return *this; }
66 self_type
& operator --() { --this->v_
; return *this; }
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_
); }
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_
; }
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;}
88 friend std::istream
& operator >>( std::istream
&i
, self_type
&x
)
91 friend std::ostream
& operator <<( std::ostream
&o
, self_type
const &x
)
94 }; // my_wrapped_integer
96 template < typename IntType
, int ID
>
97 my_wrapped_integer
<IntType
, ID
> abs( my_wrapped_integer
<IntType
, ID
> const &x
)
98 { return ( x
< my_wrapped_integer
<IntType
, ID
>(0) ) ? -x
: +x
; }
100 typedef my_wrapped_integer
<int> MyInt1
;
101 typedef my_wrapped_integer
<unsigned> MyUnsigned1
;
102 typedef my_wrapped_integer
<int, 1> MyInt2
;
103 typedef my_wrapped_integer
<unsigned, 1> MyUnsigned2
;
105 // Without these explicit instantiations, MSVC++ 6.5/7.0 does not find
106 // some friend operators in certain contexts.
112 // Various types to test with each GCD/LCM
113 typedef ::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)
120 MyInt1
> signed_test_types
;
121 typedef ::boost::mpl::list
<unsigned char, unsigned short, unsigned,
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)
129 MyUnsigned1
, MyUnsigned2
> unsigned_test_types
;
133 #define BOOST_NO_MACRO_EXPAND /**/
135 // Specialize numeric_limits for _some_ of our types
140 class numeric_limits
< MyInt1
>
142 typedef MyInt1::int_type int_type
;
143 typedef numeric_limits
<int_type
> limits_type
;
146 BOOST_STATIC_CONSTANT(bool, is_specialized
= limits_type::is_specialized
);
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
)(); }
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
);
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(); }
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
);
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
);
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(); }
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
);
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
);
187 }; // std::numeric_limits<MyInt1>
190 class numeric_limits
< MyUnsigned1
>
192 typedef MyUnsigned1::int_type int_type
;
193 typedef numeric_limits
<int_type
> limits_type
;
196 BOOST_STATIC_CONSTANT(bool, is_specialized
= limits_type::is_specialized
);
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
)(); }
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
);
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();}
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
);
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
);
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(); }
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
);
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
);
238 }; // std::numeric_limits<MyUnsigned1>
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
244 inline ostream
& operator<<(ostream
& os
, __int64 i
)
247 sprintf(buf
,"%I64d", i
);
252 inline ostream
& operator<<(ostream
& os
, unsigned __int64 i
)
255 sprintf(buf
,"%I64u", i
);
264 BOOST_AUTO_TEST_SUITE( gcd_test_suite
)
266 // GCD on signed integer types
267 BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_int_test
, T
, signed_test_types
)
270 using boost::math::gcd
;
272 using namespace boost::math
;
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) );
294 // GCD on unmarked signed integer type
295 BOOST_AUTO_TEST_CASE( gcd_unmarked_int_test
)
298 using boost::math::gcd
;
300 using namespace boost::math
;
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
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) );
325 // GCD on unsigned integer types
326 BOOST_AUTO_TEST_CASE_TEMPLATE( gcd_unsigned_test
, T
, unsigned_test_types
)
329 using boost::math::gcd
;
331 using namespace boost::math
;
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) );
346 // GCD at compile-time
347 BOOST_AUTO_TEST_CASE( gcd_static_test
)
350 using boost::math::static_gcd
;
352 using namespace boost::math
;
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 );
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
371 BOOST_AUTO_TEST_SUITE_END()
375 BOOST_AUTO_TEST_SUITE( lcm_test_suite
)
377 // LCM on signed integer types
378 BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_int_test
, T
, signed_test_types
)
381 using boost::math::lcm
;
383 using namespace boost::math
;
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) );
405 // LCM on unmarked signed integer type
406 BOOST_AUTO_TEST_CASE( lcm_unmarked_int_test
)
409 using boost::math::lcm
;
411 using namespace boost::math
;
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
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) );
436 // LCM on unsigned integer types
437 BOOST_AUTO_TEST_CASE_TEMPLATE( lcm_unsigned_test
, T
, unsigned_test_types
)
440 using boost::math::lcm
;
442 using namespace boost::math
;
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) );
457 // LCM at compile-time
458 BOOST_AUTO_TEST_CASE( lcm_static_test
)
461 using boost::math::static_lcm
;
463 using namespace boost::math
;
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 );
478 // TODO: see GCD to-do
480 BOOST_AUTO_TEST_SUITE_END()