88
99using namespace boost ::int128;
1010
11+ template <typename T>
1112void test_gcd ()
1213{
1314 // Basic tests
14- BOOST_TEST_EQ (gcd (uint128_t (12 ), uint128_t (8 )), uint128_t (4 ));
15- BOOST_TEST_EQ (gcd (uint128_t (54 ), uint128_t (24 )), uint128_t (6 ));
16- BOOST_TEST_EQ (gcd (uint128_t (48 ), uint128_t (18 )), uint128_t (6 ));
15+ BOOST_TEST_EQ (gcd (T (12 ), T (8 )), T (4 ));
16+ BOOST_TEST_EQ (gcd (T (54 ), T (24 )), T (6 ));
17+ BOOST_TEST_EQ (gcd (T (48 ), T (18 )), T (6 ));
1718
1819 // Edge cases with zero
19- BOOST_TEST_EQ (gcd (uint128_t (0 ), uint128_t (5 )), uint128_t (5 ));
20- BOOST_TEST_EQ (gcd (uint128_t (5 ), uint128_t (0 )), uint128_t (5 ));
21- BOOST_TEST_EQ (gcd (uint128_t (0 ), uint128_t (0 )), uint128_t (0 ));
20+ BOOST_TEST_EQ (gcd (T (0 ), T (5 )), T (5 ));
21+ BOOST_TEST_EQ (gcd (T (5 ), T (0 )), T (5 ));
22+ BOOST_TEST_EQ (gcd (T (0 ), T (0 )), T (0 ));
2223
2324 // Same numbers
24- BOOST_TEST_EQ (gcd (uint128_t (17 ), uint128_t (17 )), uint128_t (17 ));
25- BOOST_TEST_EQ (gcd (uint128_t (100 ), uint128_t (100 )), uint128_t (100 ));
25+ BOOST_TEST_EQ (gcd (T (17 ), T (17 )), T (17 ));
26+ BOOST_TEST_EQ (gcd (T (100 ), T (100 )), T (100 ));
2627
2728 // Coprime numbers (GCD = 1)
28- BOOST_TEST_EQ (gcd (uint128_t (13 ), uint128_t (17 )), uint128_t (1 ));
29- BOOST_TEST_EQ (gcd (uint128_t (35 ), uint128_t (64 )), uint128_t (1 ));
29+ BOOST_TEST_EQ (gcd (T (13 ), T (17 )), T (1 ));
30+ BOOST_TEST_EQ (gcd (T (35 ), T (64 )), T (1 ));
3031
3132 // Powers of 2
32- BOOST_TEST_EQ (gcd (uint128_t (16 ), uint128_t (32 )), uint128_t (16 ));
33- BOOST_TEST_EQ (gcd (uint128_t (64 ), uint128_t (128 )), uint128_t (64 ));
34- BOOST_TEST_EQ (gcd (uint128_t (1024 ), uint128_t (512 )), uint128_t (512 ));
33+ BOOST_TEST_EQ (gcd (T (16 ), T (32 )), T (16 ));
34+ BOOST_TEST_EQ (gcd (T (64 ), T (128 )), T (64 ));
35+ BOOST_TEST_EQ (gcd (T (1024 ), T (512 )), T (512 ));
3536
3637 // One divides the other
37- BOOST_TEST_EQ (gcd (uint128_t (10 ), uint128_t (100 )), uint128_t (10 ));
38- BOOST_TEST_EQ (gcd (uint128_t (7 ), uint128_t (49 )), uint128_t (7 ));
38+ BOOST_TEST_EQ (gcd (T (10 ), T (100 )), T (10 ));
39+ BOOST_TEST_EQ (gcd (T (7 ), T (49 )), T (7 ));
3940
4041 // Large 64-bit values
41- BOOST_TEST_EQ (gcd (uint128_t (1000000007 ), uint128_t (1000000009 )), uint128_t (1 ));
42- BOOST_TEST_EQ (gcd (uint128_t (UINT64_MAX), uint128_t (UINT64_MAX)), uint128_t (UINT64_MAX));
42+ BOOST_TEST_EQ (gcd (T (1000000007 ), T (1000000009 )), T (1 ));
43+ BOOST_TEST_EQ (gcd (T (UINT64_MAX), T (UINT64_MAX)), T (UINT64_MAX));
4344
4445 // Large 128-bit values
45- constexpr uint128_t large1 {0x123456789ABCDEF0ULL , 0xFEDCBA9876543210ULL };
46- constexpr uint128_t large2 {0x0F0F0F0F0F0F0F0FULL , 0xF0F0F0F0F0F0F0F0ULL };
47- BOOST_TEST (gcd (large1, large2) > uint128_t (0 )); // Just verify it doesn't crash
46+ constexpr T large1 {0x123456789ABCDEF0ULL , 0xFEDCBA9876543210ULL };
47+ constexpr T large2 {0x0F0F0F0F0F0F0F0FULL , 0xF0F0F0F0F0F0F0F0ULL };
48+ BOOST_TEST (gcd (large1, large2) > T (0 )); // Just verify it doesn't crash
4849
4950 // Mixed small and large
50- BOOST_TEST_EQ (gcd (uint128_t (1 , 0 ), uint128_t (100 )), uint128_t (4 ));
51+ BOOST_TEST_EQ (gcd (T (1 , 0 ), T (100 )), T (4 ));
5152
5253 // Fibonacci numbers (interesting GCD patterns)
53- BOOST_TEST_EQ (gcd (uint128_t (89 ), uint128_t (144 )), uint128_t (1 ));
54- BOOST_TEST_EQ (gcd (uint128_t (34 ), uint128_t (55 )), uint128_t (1 ));
54+ BOOST_TEST_EQ (gcd (T (89 ), T (144 )), T (1 ));
55+ BOOST_TEST_EQ (gcd (T (34 ), T (55 )), T (1 ));
5556}
5657
58+ template <typename T>
5759void test_lcm ()
5860{
5961 // Basic tests
60- BOOST_TEST_EQ (lcm (uint128_t (4 ), uint128_t (6 )), uint128_t (12 ));
61- BOOST_TEST_EQ (lcm (uint128_t (3 ), uint128_t (5 )), uint128_t (15 ));
62- BOOST_TEST_EQ (lcm (uint128_t (12 ), uint128_t (18 )), uint128_t (36 ));
62+ BOOST_TEST_EQ (lcm (T (4 ), T (6 )), T (12 ));
63+ BOOST_TEST_EQ (lcm (T (3 ), T (5 )), T (15 ));
64+ BOOST_TEST_EQ (lcm (T (12 ), T (18 )), T (36 ));
6365
6466 // Edge cases with zero
65- BOOST_TEST_EQ (lcm (uint128_t (0 ), uint128_t (5 )), uint128_t (0 ));
66- BOOST_TEST_EQ (lcm (uint128_t (5 ), uint128_t (0 )), uint128_t (0 ));
67- BOOST_TEST_EQ (lcm (uint128_t (0 ), uint128_t (0 )), uint128_t (0 ));
67+ BOOST_TEST_EQ (lcm (T (0 ), T (5 )), T (0 ));
68+ BOOST_TEST_EQ (lcm (T (5 ), T (0 )), T (0 ));
69+ BOOST_TEST_EQ (lcm (T (0 ), T (0 )), T (0 ));
6870
6971 // Same numbers
70- BOOST_TEST_EQ (lcm (uint128_t (7 ), uint128_t (7 )), uint128_t (7 ));
71- BOOST_TEST_EQ (lcm (uint128_t (100 ), uint128_t (100 )), uint128_t (100 ));
72+ BOOST_TEST_EQ (lcm (T (7 ), T (7 )), T (7 ));
73+ BOOST_TEST_EQ (lcm (T (100 ), T (100 )), T (100 ));
7274
7375 // Coprime numbers (LCM = a*b)
74- BOOST_TEST_EQ (lcm (uint128_t (7 ), uint128_t (11 )), uint128_t (77 ));
75- BOOST_TEST_EQ (lcm (uint128_t (13 ), uint128_t (17 )), uint128_t (221 ));
76+ BOOST_TEST_EQ (lcm (T (7 ), T (11 )), T (77 ));
77+ BOOST_TEST_EQ (lcm (T (13 ), T (17 )), T (221 ));
7678
7779 // Powers of 2
78- BOOST_TEST_EQ (lcm (uint128_t (8 ), uint128_t (16 )), uint128_t (16 ));
79- BOOST_TEST_EQ (lcm (uint128_t (32 ), uint128_t (64 )), uint128_t (64 ));
80+ BOOST_TEST_EQ (lcm (T (8 ), T (16 )), T (16 ));
81+ BOOST_TEST_EQ (lcm (T (32 ), T (64 )), T (64 ));
8082
8183 // One divides the other
82- BOOST_TEST_EQ (lcm (uint128_t (3 ), uint128_t (12 )), uint128_t (12 ));
83- BOOST_TEST_EQ (lcm (uint128_t (5 ), uint128_t (25 )), uint128_t (25 ));
84+ BOOST_TEST_EQ (lcm (T (3 ), T (12 )), T (12 ));
85+ BOOST_TEST_EQ (lcm (T (5 ), T (25 )), T (25 ));
8486
8587 // Verify LCM * GCD = a * b property
86- uint128_t a = uint128_t (42 );
87- uint128_t b = uint128_t (56 );
88+ T a = T (42 );
89+ T b = T (56 );
8890 BOOST_TEST_EQ (lcm (a, b) * gcd (a, b), a * b);
8991
9092 // Large values that won't overflow
91- BOOST_TEST_EQ (lcm (uint128_t (1000000007 ), uint128_t (1000000009 )),
92- uint128_t (1000000007 ) * uint128_t (1000000009 ));
93+ BOOST_TEST_EQ (lcm (T (1000000007 ), T (1000000009 )),
94+ T (1000000007 ) * T (1000000009 ));
9395
9496 // Test with larger values (but still safe from overflow)
95- uint128_t big1 = uint128_t (1 ) << 60 ; // 2^60
96- uint128_t big2 = uint128_t (1 ) << 61 ; // 2^61
97+ T big1 = T (1 ) << 60 ; // 2^60
98+ T big2 = T (1 ) << 61 ; // 2^61
9799 BOOST_TEST_EQ (lcm (big1, big2), big2); // LCM of powers of 2
98100}
99101
102+ template <typename T>
100103void test_gcd_lcm_properties ()
101104{
102105 // Test various mathematical properties
103106
104107 // Property: gcd(a,b) * lcm(a,b) = a * b
105- constexpr uint128_t pairs[][2 ] = {
108+ constexpr T pairs[][2 ] = {
106109 {12 , 18 },
107110 {100 , 150 },
108111 {77 , 49 },
@@ -111,27 +114,31 @@ void test_gcd_lcm_properties()
111114
112115 for (const auto & pair : pairs)
113116 {
114- uint128_t a = pair[0 ];
115- uint128_t b = pair[1 ];
117+ T a = pair[0 ];
118+ T b = pair[1 ];
116119 BOOST_TEST_EQ (gcd (a, b) * lcm (a, b), a * b);
117120 }
118121
119122 // Property: gcd(a,b) = gcd(b,a) (commutative)
120- BOOST_TEST_EQ (gcd (uint128_t (48 ), uint128_t (18 )), gcd (uint128_t (18 ), uint128_t (48 )));
123+ BOOST_TEST_EQ (gcd (T (48 ), T (18 )), gcd (T (18 ), T (48 )));
121124
122125 // Property: lcm(a,b) = lcm(b,a) (commutative)
123- BOOST_TEST_EQ (lcm (uint128_t (12 ), uint128_t (8 )), lcm (uint128_t (8 ), uint128_t (12 )));
126+ BOOST_TEST_EQ (lcm (T (12 ), T (8 )), lcm (T (8 ), T (12 )));
124127
125128 // Property: gcd(a, gcd(b, c)) = gcd(gcd(a, b), c) (associative)
126- uint128_t x = 60U , y = 48U , z = 36U ;
129+ T x = 60U , y = 48U , z = 36U ;
127130 BOOST_TEST_EQ (gcd (x, gcd (y, z)), gcd (gcd (x, y), z));
128131}
129132
130133int main ()
131134{
132- test_gcd ();
133- test_lcm ();
134- test_gcd_lcm_properties ();
135+ test_gcd<uint128_t >();
136+ test_lcm<uint128_t >();
137+ test_gcd_lcm_properties<uint128_t >();
138+
139+ test_gcd<int128_t >();
140+ test_lcm<int128_t >();
141+ test_gcd_lcm_properties<int128_t >();
135142
136143 return boost::report_errors ();
137144}
0 commit comments