Numeric
Description
The library provides overloads of standard <numeric> algorithms for safe integer types.
These operate on the non-bounded types (u8, u16, u32, u64, u128) and their verified counterparts.
#include <boost/safe_numbers/numeric.hpp>
gcd
Computes the greatest common divisor of two integers using the Euclidean algorithm.
Runtime Overload
template <non_bounded_integral_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto gcd(const T m, const T n) noexcept -> T;
Returns the greatest common divisor of m and n.
Delegates to std::gcd on the underlying hardware type, or to int128::gcd for 128-bit types.
Return Value
The greatest common divisor of m and n, as the same safe integer type T.
If both m and n are zero, returns zero.
Example
using namespace boost::safe_numbers;
auto r1 = gcd(u32{12}, u32{8}); // r1 == u32{4}
auto r2 = gcd(u32{54}, u32{24}); // r2 == u32{6}
auto r3 = gcd(u64{1000000}, u64{750000}); // r3 == u64{250000}
auto r4 = gcd(u32{7}, u32{11}); // r4 == u32{1} (coprime)
auto r5 = gcd(u32{0}, u32{42}); // r5 == u32{42}
Verified Overload
template <non_bounded_integral_library_type T>
consteval auto gcd(const verified_type_basis<T> m, const verified_type_basis<T> n) noexcept -> verified_type_basis<T>;
Compile-time only overload for verified types. Delegates to the same underlying algorithm after extracting the basis value, and wraps the result back into a verified type.
Since gcd is consteval for verified types, the result is guaranteed to be a compile-time constant.
lcm
Computes the least common multiple of two integers.
Runtime Overload
template <non_bounded_integral_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto lcm(const T m, const T n) noexcept -> T;
Returns the least common multiple of m and n.
Delegates to std::lcm on the underlying hardware type, or to int128::lcm for 128-bit types.
Return Value
The least common multiple of m and n, as the same safe integer type T.
If either m or n is zero, returns zero.
Example
using namespace boost::safe_numbers;
auto r1 = lcm(u32{4}, u32{6}); // r1 == u32{12}
auto r2 = lcm(u32{12}, u32{18}); // r2 == u32{36}
auto r3 = lcm(u64{1000}, u64{750}); // r3 == u64{3000}
auto r4 = lcm(u32{7}, u32{11}); // r4 == u32{77} (coprime)
auto r5 = lcm(u32{0}, u32{42}); // r5 == u32{0}
Verified Overload
template <non_bounded_integral_library_type T>
consteval auto lcm(const verified_type_basis<T> m, const verified_type_basis<T> n) noexcept -> verified_type_basis<T>;
Compile-time only overload for verified types. Delegates to the same underlying algorithm after extracting the basis value, and wraps the result back into a verified type.
Since lcm is consteval for verified types, the result is guaranteed to be a compile-time constant.
midpoint
Computes the midpoint of two integers without overflow.
The result is rounded towards the first argument a.
Runtime Overload
template <non_bounded_integral_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto midpoint(const T a, const T b) noexcept -> T;
Returns the midpoint of a and b, computed without overflow.
Delegates to std::midpoint on the underlying hardware type, or to int128::midpoint for 128-bit types.
Return Value
The integer midpoint of a and b, as the same safe integer type T.
When the mathematical midpoint is not an integer, the result is rounded towards a.
Example
using namespace boost::safe_numbers;
auto r1 = midpoint(u32{0}, u32{10}); // r1 == u32{5}
auto r2 = midpoint(u32{1}, u32{4}); // r2 == u32{2} (rounds towards a)
auto r3 = midpoint(u32{4}, u32{1}); // r3 == u32{3} (rounds towards a)
auto r4 = midpoint(u32{0}, u32{0}); // r4 == u32{0}
auto r5 = midpoint(u32{3}, u32{3}); // r5 == u32{3}
Verified Overload
template <non_bounded_integral_library_type T>
consteval auto midpoint(const verified_type_basis<T> a, const verified_type_basis<T> b) noexcept -> verified_type_basis<T>;
Compile-time only overload for verified types. Delegates to the same underlying algorithm after extracting the basis value, and wraps the result back into a verified type.
Since midpoint is consteval for verified types, the result is guaranteed to be a compile-time constant.