C++ Basics: Compare Repeating Periods with gcd and lcm
Find a shared time unit and the next common boundary for two small integer periods.
Prepare a scratch directory
Tested on Linux x86_64 with GCC 14.2.0. Install a C++20-capable compiler and standard-library development headers, with g++ on PATH. You also need Bash, a text editor, and the mktemp, rm, and rmdir utilities. No third-party library is required.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_directory="$PWD"
work_directory="$(mktemp -d)" || exit 1
cd -- "$work_directory" || exit 1Run the example
Save this as gcd-lcm-periods-demo.cpp:
#include <iostream>
#include <numeric>
int main()
{
const unsigned first = 12;
const unsigned second = 18;
std::cout << "Shared unit: " << std::gcd(first, second) << '\n';
std::cout << "Common boundary: " << std::lcm(first, second) << '\n';
std::cout << "Zero input: " << std::lcm(0u, second) << '\n';
}Compile and run it. The program runs only after compilation succeeds:
g++ -std=c++20 -Wall -Wextra -Werror -pedantic gcd-lcm-periods-demo.cpp -o gcd-lcm-periods-demo &&
./gcd-lcm-periods-demoObserved output:
Shared unit: 6
Common boundary: 36
Zero input: 0Read the result
Periods of 12 and 18 units share a greatest common divisor of 6. If both start together at zero, they align again at 36 units, their least common multiple. The zero-input result is a library rule, not a usable recurring schedule.
Apply it carefully
These functions operate on integers other than bool. Their common result type must represent the magnitudes of both inputs, and std::lcm also requires the result to fit. Overflow is not reported as an exception. Validate externally supplied periods and their possible least common multiple before calling it; merely changing to unsigned does not make an overflowing lcm safe. Nonzero phase offsets require a different scheduling calculation.
The C++ working draft describes the relevant rules. This example builds in C++20 mode; the current working draft also documents later additions.
Clean up
Remove only the source and executable created here, then return to the starting directory:
rm -- gcd-lcm-periods-demo.cpp gcd-lcm-periods-demo
cd -- "$start_directory" || exit 1
rmdir -- "$work_directory"
unset start_directory work_directoryIf the directory is not empty, inspect its remaining contents before removing anything else.
Acknowledgements
This post was created with assistance from AI.