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).

#include <boost/safe_numbers/numeric.hpp>

gcd

Computes the greatest common divisor of two integers using the Euclidean algorithm.

template <non_bounded_integral_library_type T>
[[nodiscard]] 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.

Parameters

  • m — The first value.

  • n — The second value.

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.

Complexity

O(log(min(m, n))) divisions (Euclidean algorithm).

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}

lcm

Computes the least common multiple of two integers.

template <non_bounded_integral_library_type T>
[[nodiscard]] 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.

Parameters

  • m — The first value.

  • n — The second value.

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.

Complexity

O(log(min(m, n))) divisions (via gcd).

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}

midpoint

Computes the midpoint of two integers without overflow. The result is rounded towards the first argument a.

template <non_bounded_integral_library_type T>
[[nodiscard]] 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.

Parameters

  • a — The first value. The result rounds towards this value.

  • b — The second value.

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.

Complexity

O(1).

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}