Integer Utilities
Description
The library provides utility functions for safe integer types.
These operate on the non-bounded unsigned types (u8, u16, u32, u64, u128) and their verified counterparts.
#include <boost/safe_numbers/integer_utilities.hpp>
isqrt
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto isqrt(const T val) -> T;
Returns the integer square root of val, i.e., the largest integer r such that r * r <= val.
Uses Newton’s method on the underlying hardware type. The computation cannot overflow and converges rapidly.
Verified Overload
template <non_bounded_unsigned_library_type T>
consteval auto isqrt(const verified_type_basis<T> val) -> verified_type_basis<T>;
Compile-time only overload for verified types. Delegates to the runtime overload after extracting the basis value, and wraps the result back into a verified type.
Since isqrt is consteval for verified types, the result is guaranteed to be a compile-time constant.
remove_trailing_zeros
Removes trailing decimal zeros from an unsigned integer value using a branchless algorithm based on modular multiplicative inverses (Granlund-Montgomery division).
Return Type
template <typename UInt>
struct remove_trailing_zeros_return
{
UInt trimmed_number;
std::size_t number_of_removed_zeros;
};
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto remove_trailing_zeros(const T n);
Removes all trailing decimal zeros from n.
Returns a remove_trailing_zeros_return containing the trimmed value and the count of removed zeros, such that trimmed_number * 10^number_of_removed_zeros == n.
The algorithm is entirely branchless (no data-dependent branches), operating via modular inverse multiplication and bit rotation.
It processes the exponent in O(log(max_digits)) steps, where max_digits is the maximum number of decimal digits for the type.
Return Value
A remove_trailing_zeros_return where:
-
trimmed_numberisnwith all trailing decimal zeros removed. -
number_of_removed_zerosis the count of removed zeros.
Supported Types and Ranges
| Type | Max Trailing Zeros | Algorithm Steps |
|---|---|---|
|
2 |
2 |
|
4 |
3 |
|
9 |
4 |
|
19 |
5 |
|
38 |
6 |
Example
using namespace boost::safe_numbers;
auto r1 = remove_trailing_zeros(u32{12300});
// r1.trimmed_number == 123, r1.number_of_removed_zeros == 2
auto r2 = remove_trailing_zeros(u64{1000000});
// r2.trimmed_number == 1, r2.number_of_removed_zeros == 6
auto r3 = remove_trailing_zeros(u8{static_cast<std::uint8_t>(7)});
// r3.trimmed_number == 7, r3.number_of_removed_zeros == 0
Verified Overload
template <non_bounded_unsigned_library_type T>
consteval auto remove_trailing_zeros(const verified_type_basis<T> val);
Compile-time-only overload for verified types. Delegates to the detail implementation after extracting the underlying value.
Since remove_trailing_zeros is consteval for verified types, the result is guaranteed to be a compile-time constant.
is_power_10
Tests whether an unsigned integer value is an exact power of 10 (i.e., one of 1, 10, 100, 1000, …).
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto is_power_10(const T n) -> bool;
Verified Overload
template <non_bounded_unsigned_library_type T>
consteval auto is_power_10(const verified_type_basis<T> n) -> bool;
Compile-time-only overload for verified types.
Since is_power_10 is consteval for verified types, the result is guaranteed to be a compile-time constant and can be used directly in static_assert.
log2
Returns the integer base-2 logarithm (floor of log2) of a value.
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto log2(const T n) noexcept -> int;
Computes floor(log2(n)) using bit_width(n) - 1.
log10
Returns the integer base-10 logarithm (floor of log10) of a value.
Uses an O(1) algorithm based on the most significant bit position to approximate log10, refined with a single power-of-10 table lookup.
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto log10(const T n) noexcept -> int;
Computes floor(log10(n)) using num_digits(n) - 1, where num_digits approximates the digit count via log10(x) ~{equals} log2(x) / log2(10) and refines with at most two comparisons against a power-of-10 lookup table.
ipow
Integer exponentiation using the exponentiation-by-squaring algorithm.
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto ipow(const T a, const T b) noexcept -> T;
Computes a raised to the power b using exponentiation by squaring.
The algorithm runs in O(log(b)) multiplications:
-
If
b == 0, returnsT{1}. -
If
bis odd, returnsa * ipow(a, b - 1). -
If
bis even, returnsipow(a, b / 2)^2.
If the result overflows the type, the behavior follows the overflow policy of the safe integer type (by default, throwing std::overflow_error).
Verified Overload
template <non_bounded_unsigned_library_type T>
consteval auto ipow(const verified_type_basis<T> a, const verified_type_basis<T> b) -> verified_type_basis<T>;
Compile-time only overload for verified types. Returns a verified type, preserving the compile-time guarantee.
Since ipow is consteval for verified types, the computation is guaranteed to occur at compile time. Overflow produces a compile error.
is_power_2
Tests whether an unsigned integer value is an exact power of 2 (i.e., has exactly one bit set).
Runtime Overload
template <non_bounded_unsigned_library_type T>
requires (!is_verified_type_v<T>)
constexpr auto is_power_2(const T n) noexcept -> bool;
Verified Overload
template <non_bounded_unsigned_library_type T>
consteval auto is_power_2(const verified_type_basis<T> n) noexcept -> bool;
Compile-time-only overload for verified types.
Since is_power_2 is consteval for verified types, the result is guaranteed to be a compile-time constant and can be used directly in static_assert.