<numeric> Support

Saturating Arithmetic

Saturating arithmetic avoids the possibility of overflow or underflow, by clamping the value to a defined range should either of these situations occur. This means that on overflow the types will return std::numeric_limits::max(), and on underflow they will return std::numeric_limits::min(). The following functions are provided for saturating arithmetic, and they do not require C++26.

#include <boost/int128/numeric.hpp>

namespace boost {
namespace int128 {

BOOST_INT128_HOST_DEVICE constexpr uint128_t add_sat(uint128_t lhs, uint128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t add_sat(int128_t lhs, int128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr uint128_t sub_sat(uint128_t lhs, uint128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t sub_sat(int128_t lhs, int128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr uint128_t mul_sat(uint128_t lhs, uint128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t mul_sat(const int128_t& lhs, const int128_t& rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr uint128_t div_sat(uint128_t lhs, uint128_t rhs) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t div_sat(int128_t lhs, int128_t rhs) noexcept;

} // namespace int128
} // namespace boost

Saturating Cast

This function converts a uint128_t or int128_t to a TargetType, saturating rather than wrapping when the value is out of the target’s range. TargetType is constrained (via SFINAE) to the library’s set of reduced integer types: the standard signed and unsigned integer types (excluding bool and plain char), int128_t, uint128_t, and the compiler’s native 128-bit integer types where available. Should the TargetType not be able to represent the value it is set to either std::numeric_limits<TargetType>::max() or std::numeric_limits<TargetType>::min() depending on whether the situation is overflow or underflow.

#include <boost/int128/numeric.hpp>

namespace boost {
namespace int128 {

template <typename TargetType>
BOOST_INT128_HOST_DEVICE constexpr TargetType saturate_cast(uint128_t value) noexcept;

template <typename TargetType>
BOOST_INT128_HOST_DEVICE constexpr TargetType saturate_cast(int128_t value) noexcept;

} // namespace int128
} // namespace boost

Greatest Common Divisor (GCD)

Computes the greatest common divisor of a and b.

#include <boost/int128/numeric.hpp>

namespace boost {
namespace int128 {

BOOST_INT128_HOST_DEVICE constexpr uint128_t gcd(uint128_t a, uint128_t b) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t gcd(const int128_t a, const int128_t b) noexcept;

} // namespace int128
} // namespace boost

Least Common Multiple (LCM)

Computes the least common multiple of a and b.

#include <boost/int128/numeric.hpp>

namespace boost {
namespace int128 {

BOOST_INT128_HOST_DEVICE constexpr uint128_t lcm(uint128_t a, uint128_t b) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t lcm(const int128_t a, const int128_t b) noexcept;

} // namespace int128
} // namespace boost

Midpoint

Computes the midpoint of a and b, rounding towards a.

#include <boost/int128/numeric.hpp>

namespace boost {
namespace int128 {

BOOST_INT128_HOST_DEVICE constexpr uint128_t midpoint(uint128_t a, uint128_t b) noexcept;

BOOST_INT128_HOST_DEVICE constexpr int128_t midpoint(const int128_t a, const int128_t b) noexcept;

} // namespace int128
} // namespace boost