Skip to content

Commit bebbaa3

Browse files
committed
Add test set
1 parent 142b506 commit bebbaa3

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

test/Jamfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ run test_sign_compare.cpp ;
7373
compile-fail test_fail_sign_compare.cpp ;
7474
run test_x64_msvc_div.cpp ;
7575

76+
run test_gcd_lcm.cpp ;
77+
7678
# Make sure we run the examples as well
7779
run ../examples/construction.cpp ;
7880
run ../examples/bit.cpp ;

test/test_gcd_lcm.cpp

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright 2025 Matt Borland
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// https://www.boost.org/LICENSE_1_0.txt
4+
5+
#include <boost/int128.hpp>
6+
#include <boost/core/lightweight_test.hpp>
7+
#include <limits>
8+
9+
using namespace boost::int128;
10+
11+
void test_gcd()
12+
{
13+
// 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));
17+
18+
// 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));
22+
23+
// 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));
26+
27+
// 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));
30+
31+
// 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));
35+
36+
// 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));
39+
40+
// 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));
43+
44+
// 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
48+
49+
// Mixed small and large
50+
BOOST_TEST_EQ(gcd(uint128_t(1, 0), uint128_t(100)), uint128_t(4));
51+
52+
// 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));
55+
}
56+
57+
void test_lcm()
58+
{
59+
// 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));
63+
64+
// 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));
68+
69+
// 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+
73+
// 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+
77+
// 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+
81+
// 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+
85+
// Verify LCM * GCD = a * b property
86+
uint128_t a = uint128_t(42);
87+
uint128_t b = uint128_t(56);
88+
BOOST_TEST_EQ(lcm(a, b) * gcd(a, b), a * b);
89+
90+
// 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+
94+
// 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+
BOOST_TEST_EQ(lcm(big1, big2), big2); // LCM of powers of 2
98+
}
99+
100+
void test_gcd_lcm_properties()
101+
{
102+
// Test various mathematical properties
103+
104+
// Property: gcd(a,b) * lcm(a,b) = a * b
105+
constexpr uint128_t pairs[][2] = {
106+
{12, 18},
107+
{100, 150},
108+
{77, 49},
109+
{1024, 768}
110+
};
111+
112+
for (const auto& pair : pairs)
113+
{
114+
uint128_t a = pair[0];
115+
uint128_t b = pair[1];
116+
BOOST_TEST_EQ(gcd(a, b) * lcm(a, b), a * b);
117+
}
118+
119+
// 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)));
121+
122+
// 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)));
124+
125+
// Property: gcd(a, gcd(b, c)) = gcd(gcd(a, b), c) (associative)
126+
uint128_t x = 60U, y = 48U, z = 36U;
127+
BOOST_TEST_EQ(gcd(x, gcd(y, z)), gcd(gcd(x, y), z));
128+
}
129+
130+
int main()
131+
{
132+
test_gcd();
133+
test_lcm();
134+
test_gcd_lcm_properties();
135+
136+
return boost::report_errors();
137+
}

0 commit comments

Comments
 (0)