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