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

lcm

Computes the least common multiple of two integers.

template <non_bounded_integral_library_type T>
BOOST_SAFE_NUMBERS_HOST_DEVICE [[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).

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

Examples

Example 1. This example demonstrates the numeric algorithms with safe integer types.
// Copyright 2026 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/safe_numbers/numeric.hpp>
#include <boost/safe_numbers/unsigned_integers.hpp>
#include <boost/safe_numbers/iostream.hpp>
#include <iostream>

int main()
{
    using namespace boost::safe_numbers;

    // gcd: greatest common divisor (Euclidean algorithm)
    std::cout << "gcd(12, 8)      = " << gcd(u32{12}, u32{8}) << '\n';
    std::cout << "gcd(54, 24)     = " << gcd(u32{54}, u32{24}) << '\n';
    std::cout << "gcd(7, 11)      = " << gcd(u32{7}, u32{11}) << '\n';
    std::cout << "gcd(0, 42)      = " << gcd(u32{0}, u32{42}) << '\n';

    std::cout << '\n';

    // lcm: least common multiple
    std::cout << "lcm(4, 6)       = " << lcm(u32{4}, u32{6}) << '\n';
    std::cout << "lcm(12, 18)     = " << lcm(u32{12}, u32{18}) << '\n';
    std::cout << "lcm(7, 11)      = " << lcm(u32{7}, u32{11}) << '\n';

    std::cout << '\n';

    // midpoint: average without overflow, rounded toward the first argument
    std::cout << "midpoint(0, 10) = " << midpoint(u32{0}, u32{10}) << '\n';
    std::cout << "midpoint(1, 4)  = " << midpoint(u32{1}, u32{4}) << '\n';
    std::cout << "midpoint(4, 1)  = " << midpoint(u32{4}, u32{1}) << '\n';

    return 0;
}

Output:

gcd(12, 8)      = 4
gcd(54, 24)     = 6
gcd(7, 11)      = 1
gcd(0, 42)      = 42

lcm(4, 6)       = 12
lcm(12, 18)     = 36
lcm(7, 11)      = 77

midpoint(0, 10) = 5
midpoint(1, 4)  = 2
midpoint(4, 1)  = 3