Mathematical Types and Operations

Integer Math

Introduction

Integer Conversion

The integer_conversion module provides utility functions for converting between integer operand types and their native integer representations.

toNativeInteger

toNativeInteger converts an integer operand to its native integer value. For SaturatingInteger types, it unwraps the value via toRawValue(). Native integers pass through unchanged.

toSaturatingInteger

toSaturatingInteger converts an integer operand to a SaturatingInteger. SaturatingInteger values pass through unchanged, while native integers are wrapped.

Unsigned Absolute Values

toUnsignedAbsolute converts a native integer into an unsigned value of the same width. It exists because std::abs() cannot represent the absolute value of the minimum signed integer in the same signed type. An unsigned integer of the same width can represent that magnitude, and unsigned input values are returned unchanged.

Integer Range

IntegerRange is a compact inclusive range for native integer values. It safely compares mixed signed and unsigned integer operands for containment checks and can clamp incoming values without relying on unsafe casts.

Signed Magnitude

SignedMagnitude represents a same-width integer value as a sign and an unsigned magnitude. This is useful when you write constexpr integer algorithms that must handle values such as the signed minimum value without ever evaluating an overflowing signed expression.

The type is deliberately small. It is not meant to replace normal integers in user-facing data models. Use it when an algorithm temporarily needs a wider mathematical view of a native integer domain, especially when signed and unsigned inputs meet.

Creating Values

Use SignedMagnitude::fromValue when you start from a native integer or from a SaturatingInteger. The source operand’s native integer must have the same byte width as the template argument.

using Magnitude = el::SignedMagnitude<std::int32_t>;

constexpr auto negative = Magnitude::fromValue(std::int32_t{-5});
constexpr auto unsignedValue = Magnitude::fromValue(std::uint32_t{0x8000'0000U});
constexpr auto saturatedValue = Magnitude::fromValue(el::SatInt32{-5});

Use SignedMagnitude::fromSignAndMagnitude when the sign and absolute magnitude are already available. Zero is always normalized to a positive value, so there is only one representation for zero.

Bounded Conversion

Use SignedMagnitude::toSaturatingValue to convert back to the native result type. The explicit bounds are applied before the native conversion, which keeps signed-minimum magnitudes and unsigned values above a signed maximum safe in constant expressions.

using Magnitude = el::SignedMagnitude<std::int32_t>;

constexpr auto value = Magnitude::fromValue(std::uint32_t{0x8000'0000U});
constexpr auto clamped = value.toSaturatingValue(
    std::numeric_limits<std::int32_t>::min(),
    std::numeric_limits<std::int32_t>::max()); // 2147483647

Use SignedMagnitude::wouldSaturate when you need to know if the conversion would clamp instead of returning an exact native result.

Bounded Addition

Use SignedMagnitude::saturatingAddBounded for addition in the sign/magnitude domain. The method is the shared implementation behind the constexpr bounded addition and subtraction helpers.

using Magnitude = el::SignedMagnitude<std::uint8_t>;

constexpr auto index = Magnitude::fromValue(std::uint8_t{5});
constexpr auto movement = Magnitude::fromValue(std::int8_t{-8});
constexpr auto result = index.saturatingAddBounded(movement, std::uint8_t{0}, std::uint8_t{254}); // 0

Use SignedMagnitude::wouldAddBoundedSaturate to distinguish exact sums from clamped sums.

Bounded Multiplication, Division and Modulo

Use SignedMagnitude::saturatingMultiplyBounded, SignedMagnitude::saturatingDivideBounded, and SignedMagnitude::saturatingModuloBounded for the remaining bounded arithmetic operations in the sign/magnitude domain. These methods are the shared implementation behind the constexpr bounded multiplication, division, and modulo helpers.

using Magnitude = el::SignedMagnitude<std::int32_t>;

constexpr auto minimum = std::numeric_limits<std::int32_t>::min();
constexpr auto maximum = std::numeric_limits<std::int32_t>::max();
constexpr auto value = Magnitude::fromValue(minimum);
constexpr auto divided = value.saturatingDivideBounded(Magnitude::fromValue(std::int32_t{-1}), minimum, maximum);
// divided == maximum

Use the matching would...Saturate methods to distinguish exact results from clamped results. Division and modulo by zero terminate.

Saturating Math

Introduction

Saturating Integer

SaturatingInteger is a small integer wrapper for calculations where overflow must never wrap around silently. When an operation exceeds the native integer range, the value is clamped to the nearest representable limit. For example, adding 20 to SatInt8{120} produces 127 instead of wrapping to a negative number.

This is useful for counters, sizes, terminal layout calculations, progress values, and other places where a clipped result is safer and easier to reason about than undefined behavior or modulo-style overflow.

Available Types

The library provides signed and unsigned aliases for the fixed-width integer sizes:

Basic Usage

Use operators when both operands have compatible signedness and you want the result type to grow to the larger operand size.

#include <erbsland/math/SaturatingInteger.hpp>

auto small = el::SatInt8{100};
auto larger = el::SatInt16{40};
auto result = small + larger; // el::SatInt16{140}

Use the named arithmetic methods when the result shall keep the current type, or when mixed signedness is intentional. The value-returning methods are added, subtracted, absoluteDifference, multiplied, divided, and modulo.

auto value = el::SatInt8{120};
auto clipped = value.added(20); // el::SatInt8{127}

auto mixed = math::SatUInt8{10}.subtracted(el::SatInt8{20}); // el::SatUInt8{0}

Use the mutating methods add, subtract, multiply, divide, and applyModulo when the operation should update the existing object.

auto column = el::SatUInt16{250};
column.add(20);         // 270
column.applyModulo(80); // 30
Conversions and Helpers

toRawValue returns the wrapped integer. cast converts to another saturating integer type, and castOrThrow converts without clipping or throws OverflowError. toSizeT converts to std::size_t with saturation. toAbsolute keeps the current type, while toUnsignedAbsolute returns the matching unsigned type so the minimum signed value can be represented exactly.

auto negative = el::SatInt8{-128};

auto sameType = negative.toAbsolute();         // el::SatInt8{127}
auto unsignedType = negative.toUnsignedAbsolute(); // el::SatUInt8{128}
auto asSize = negative.toSizeT();              // std::size_t{0}

Use range, clamp, and clamped for inclusive range handling. wrap and wrapped apply modulo-style wrapping into a range. The count-returning variants wrapAndCount and wrappedAndCount additionally report how often the value crossed the range boundary. Values below the range return a negative count, values above the range return a positive count, and values already in range return zero. Reversed direct bounds and ranges outside the native value range produce zero.

auto minute = el::SatInt16{75}.wrapped(0, 59); // el::SatInt16{15}

auto seconds = el::SatInt64{-1};
auto days = seconds.wrapAndCount(0, 86'399); // seconds == 86'399, days == -1

The predicates isZero, isOne, isNegative, isMinimum, and isMaximum make boundary checks readable. Use wouldAddSaturate, wouldSubtractSaturate, wouldMultiplySaturate, wouldDivideSaturate, and wouldModuloSaturate when you need to know if an operation would clip before you apply it.

auto width = el::SatUInt8{250};

if (width.wouldAddSaturate(20)) {
    width = el::SatUInt8::maximum();
}
Static Construction

The static fromAddition, fromSubtraction, fromMultiplication, fromDivision, and fromModulo methods create a value directly from an operation. They are useful when the target type should be explicit at the call site.

auto sum = el::SatInt8::fromAddition(120, 20);       // el::SatInt8{127}
auto product = el::SatUInt8::fromMultiplication(20U, 20U); // el::SatUInt8{255}

For division algorithms, fromDivisionWithRemainder returns quotient first and remainder second. The matching mutating helpers are divideGetRemainder and divideKeepRemainder.

auto [quotient, remainder] = el::SatInt8::fromDivisionWithRemainder(127, 10);
// quotient == 12, remainder == 7

Saturating Integer Types

The SaturatingIntegerTypes header provides type traits and concepts for identifying SaturatingInteger types.

Type Trait
IsSaturatingInteger<T>

A type trait that is std::true_type when T is a SaturatingInteger<NativeInteger>, and std::false_type otherwise.

Concept
SaturatingIntegerType<T>

A concept that is satisfied when T is a SaturatingInteger type. This is a convenience wrapper around IsSaturatingInteger.

Saturating Math Functions

The saturating math functions are low-level integer helpers for calculations where overflow must be clipped instead of wrapped. They operate on native integer types and return native integer values. If you want a value type with operators and named member functions, use SaturatingInteger instead.

For arithmetic operations, saturation means that a result beyond the target type range is clamped to std::numeric_limits<T>::min() or std::numeric_limits<T>::max(). For casts, values below the target range become the target minimum, and values above the target range become the target maximum.

Arithmetic

Use saturatingAdd, saturatingSubtract, saturatingMultiply, saturatingDivide, and saturatingModulo for arithmetic that keeps the result in the range of the first operand type.

#include <erbsland/math/SaturatingMath.hpp>

auto a = std::int8_t{120};
auto b = std::int8_t{20};
auto sum = el::saturatingAdd(a, b); // std::int8_t{127}

auto count = std::uint8_t{5};
auto remaining = el::saturatingSubtract(count, 10); // std::uint8_t{0}
Mixed Types

The mixed-type overloads allow the second operand to use another compatible integer type. They still keep the first operand type as the result type. This makes the target range explicit at the call site.

auto width = std::uint8_t{250};
auto next = el::saturatingAdd(width, std::uint16_t{20}); // std::uint8_t{255}

auto offset = std::int8_t{-100};
auto scaled = el::saturatingMultiply(offset, std::int16_t{3}); // std::int8_t{-128}
Division and Modulo

saturatingDivide clips the signed minimum divided by -1 to the signed maximum, because the mathematical result cannot be represented in the same signed type. saturatingModulo returns 0 for the matching minimum % -1 edge case.

auto quotient = el::saturatingDivide(std::int8_t{-128}, std::int8_t{-1}); // std::int8_t{127}
auto remainder = el::saturatingModulo(std::int8_t{-128}, std::int8_t{-1}); // std::int8_t{0}

Division and modulo by zero are programming errors. These functions are noexcept and call std::terminate() for a zero divisor.

Saturating Casts

Use saturatingCast to convert between integer types without wrapping. Use willCastOverflow when you need to know whether the conversion would change the value by clipping it. For example, converting the unsigned 16-bit value 0x2000 into an unsigned 8-bit value produces 0xff. Converting a negative signed value such as -10 into an unsigned type produces the unsigned target minimum, which is zero.

auto small = el::saturatingCast<std::uint8_t>(500); // std::uint8_t{255}
auto none = el::saturatingCast<std::uint8_t>(-5);   // std::uint8_t{0}

if (el::willCastOverflow<std::uint8_t>(300)) {
    // The cast would be clipped to 255.
}
Overflow Prediction

Use willAddOverflow, willSubtractOverflow, willMultiplyOverflow, willDivideOverflow, and willModuloOverflow to test whether an operation would need saturation before you perform it.

auto value = std::int8_t{120};

if (el::willAddOverflow(value, 20)) {
    value = std::numeric_limits<std::int8_t>::max();
} else {
    value += 20;
}
Increment and Decrement

saturatingIncrement and saturatingDecrement update an integer in place and stop at the type limits.

auto cursor = std::uint8_t{255};
math::saturatingIncrement(cursor); // still 255

auto signedValue = std::int8_t{-128};
math::saturatingDecrement(signedValue); // still -128

Constexpr Saturating Math

The constexpr saturating math helpers are small native-integer tools for code that must work in constant expressions. Use them when you need saturating arithmetic inside value types, templates, or other APIs that promise constexpr behavior.

Unlike Saturating Math, these helpers do not use compiler overflow intrinsics. They are intentionally limited to same-width operands and explicit result bounds. This makes the edge cases easy to reason about while still supporting signed and unsigned combinations.

Internally, these helpers use SignedMagnitude to avoid signed overflow in constant expressions. Use that type directly only when you are building similar low-level integer algorithms.

Bounded Arithmetic

Use saturatingAddBounded and saturatingSubtractBounded when the result must be clamped to an explicit domain range instead of the natural type range.

#include <erbsland/math/ConstexprSaturatingMath.hpp>

constexpr auto index = std::uint8_t{250};
constexpr auto moved = el::saturatingAddBounded(
    index, std::int8_t{10}, std::uint8_t{0}, std::uint8_t{254}); // 254

constexpr auto offset = el::saturatingSubtractBounded(
    std::uint32_t{0},
    std::uint32_t{0x8000'0000U},
    std::numeric_limits<std::int32_t>::min(),
    std::numeric_limits<std::int32_t>::max()); // -2147483648

Use willAddBoundedSaturate and willSubtractBoundedSaturate when you need to distinguish an exact result from a clamped one.

Negation and Steps

Use saturatingNegateBounded for signed negation that must also work for the minimum signed value and for unsigned input values.

Use saturatingIncrementBounded and saturatingDecrementBounded for one-step movement inside custom bounds.

Multiplication, Division and Modulo

Use saturatingMultiplyBounded, saturatingDivideBounded, and saturatingModuloBounded for same-width scalar arithmetic inside custom bounds. Division and modulo by zero terminate, matching the non-constexpr saturating math helpers.

Use the matching will...Saturate helpers when you need to distinguish exact results from clamped results.

Arbitrary-Precision Integers

Introduction

BigUnsignedInteger and BigInteger represent integers whose size is limited only by available memory. They are useful when calculations can exceed native integer limits and saturating arithmetic would lose information.

The API deliberately covers the common integer operations only. It has no bitwise operations, mixed native/big-integer operators, powers, or number-theory helpers. Construct native operands explicitly before combining them with a big integer.

Construction and Text

Both types default to zero and accept native integers through explicit constructors. Constructing a BigUnsignedInteger from a negative native value throws an OverflowError.

toString() creates canonical decimal text. fromString() parses a complete decimal value and returns an empty optional for invalid input, while fromStringOrThrow() reports invalid text with ParseError. Parsing accepts an optional leading plus sign; BigInteger also accepts a minus sign. Whitespace, digit separators, and base prefixes are not accepted.

Arithmetic

Both types support comparison, addition, subtraction, multiplication, division, modulo, and the corresponding compound assignments. Operands must have the same big-integer type. Arithmetic is exact, except that subtracting a larger value from BigUnsignedInteger throws OverflowError.

Division truncates toward zero. A BigInteger remainder has the dividend’s sign. divideGetRemainder() performs quotient and remainder calculation together: it stores the quotient in the object and returns the remainder. As with native and saturating integer arithmetic, division or modulo by zero terminates the process.

Native Conversion

cast<T>() converts to a native integer and clamps values outside the target range. castOrThrow<T>() instead requires an exact representation and throws OverflowError when the value is outside the target range. Negative values clamp to zero when casting to an unsigned native type.

Integer Bit and Byte-Order Operations

The integer bit operations provide compiler-safe rotations and byte-order conversion for unsigned native integers. All operations are constexpr and independent of host byte order, alignment, and aliasing. They use fixed-extent byte spans so the required number of bytes is part of the function signature.

Interface

class BigInteger

An arbitrary-precision signed integer.

Arithmetic is exact and division truncates toward zero. A remainder has the dividend’s sign. Division and modulo by zero terminate the process. Operators intentionally accept only another BigInteger; use an explicit constructor when starting from a native integer.

See: Mathematical Types and Operations

Public Functions

BigInteger() = default

Create a zero value.

template<NativeInteger T>
explicit BigInteger(T value)

Create a value from a native integer.

Template Parameters:

T – The native integer type.

Parameters:

value – The initial value.

explicit BigInteger(BigUnsignedInteger magnitude) noexcept

Create a positive value from an unsigned magnitude.

Parameters:

magnitude – The initial magnitude.

std::strong_ordering operator<=>(const BigInteger &other) const noexcept

Compare this value mathematically with another value.

Parameters:

other – The other value.

Returns:

The ordering of this value compared with other.

BigInteger operator+(const BigInteger &other) const

Add another value.

Parameters:

other – The value to add.

Returns:

The exact sum.

BigInteger &operator+=(const BigInteger &other)

Add another value in place.

Parameters:

other – The value to add.

Returns:

This value after the addition.

BigInteger operator-(const BigInteger &other) const

Subtract another value.

Parameters:

other – The value to subtract.

Returns:

The exact difference.

BigInteger &operator-=(const BigInteger &other)

Subtract another value in place.

Parameters:

other – The value to subtract.

Returns:

This value after the subtraction.

BigInteger operator-() const

Negate this value.

Returns:

The exact negated value.

BigInteger operator*(const BigInteger &other) const

Multiply by another value.

Parameters:

other – The factor.

Returns:

The exact product.

BigInteger &operator*=(const BigInteger &other)

Multiply by another value in place.

Parameters:

other – The factor.

Returns:

This value after the multiplication.

BigInteger operator/(const BigInteger &other) const

Divide by another value, truncating toward zero.

Parameters:

other – The divisor, which must not be zero.

Returns:

The quotient.

BigInteger &operator/=(const BigInteger &other)

Divide by another value in place, truncating toward zero.

Parameters:

other – The divisor, which must not be zero.

Returns:

This value after the division.

BigInteger operator%(const BigInteger &other) const

Calculate the remainder of a division.

Parameters:

other – The divisor, which must not be zero.

Returns:

The remainder, with the same sign as this value.

BigInteger &operator%=(const BigInteger &other)

Store the remainder of a division in place.

Parameters:

other – The divisor, which must not be zero.

Returns:

This value after the modulo operation.

bool isZero() const noexcept

Test whether this value is zero.

bool isOne() const noexcept

Test whether this value is one.

bool isNegative() const noexcept

Test whether this value is negative.

const BigUnsignedInteger &magnitude() const noexcept

Get the absolute magnitude.

template<NativeInteger T>
T cast() const

Cast this value to a native integer, clamping it to the target range.

Template Parameters:

T – The target native integer type.

Returns:

The converted value.

template<NativeInteger T>
T castOrThrow() const

Cast this value to a native integer without clamping.

Template Parameters:

T – The target native integer type.

Throws:

err::OverflowError – If this value cannot be represented by T.

Returns:

The converted value.

text::String toString() const

Convert this value to decimal text.

BigInteger negated() const

Return this value with its sign changed.

BigInteger divideGetRemainder(const BigInteger &divisor)

Divide this value in place and return the remainder.

Parameters:

divisor – The divisor, which must not be zero.

Returns:

The remainder, with the dividend’s original sign.

Public Static Functions

static std::optional<BigInteger> fromString(const text::String &text)

Parse a complete decimal value.

Parameters:

text – The text to parse.

Returns:

The parsed value, or an empty optional for invalid text.

static BigInteger fromStringOrThrow(const text::String &text)

Parse a complete decimal value.

Parameters:

text – The text to parse.

Throws:

err::ParseError – If text is not a valid signed decimal integer.

Returns:

The parsed value.

static BigInteger fromSignAndMagnitude(bool negative, BigUnsignedInteger magnitude) noexcept

Create a value from a sign and an unsigned magnitude.

Parameters:
  • negative – Whether the value shall be negative.

  • magnitude – The absolute magnitude.

Returns:

The normalized value. A zero magnitude is always positive.

class BigUnsignedInteger

An arbitrary-precision unsigned integer.

Arithmetic is exact except for subtraction below zero, which throws an overflow error. Division and modulo by zero terminate the process. Operators intentionally accept only another BigUnsignedInteger; use an explicit constructor when starting from a native integer.

See: Mathematical Types and Operations

Public Functions

BigUnsignedInteger() = default

Create a zero value.

template<NativeInteger T>
explicit BigUnsignedInteger(T value)

Create a value from a native integer.

Template Parameters:

T – The native integer type.

Parameters:

value – The initial value.

Throws:

err::OverflowError – If value is negative.

std::strong_ordering operator<=>(const BigUnsignedInteger &other) const noexcept

Compare this value mathematically with another value.

Parameters:

other – The other value.

Returns:

The ordering of this value compared with other.

BigUnsignedInteger operator+(const BigUnsignedInteger &other) const

Add another value.

Parameters:

other – The value to add.

Returns:

The exact sum.

BigUnsignedInteger &operator+=(const BigUnsignedInteger &other)

Add another value in place.

Parameters:

other – The value to add.

Returns:

This value after the addition.

BigUnsignedInteger operator-(const BigUnsignedInteger &other) const

Subtract another value.

Parameters:

other – The value to subtract.

Throws:

err::OverflowError – If other is larger than this value.

Returns:

The exact difference.

BigUnsignedInteger &operator-=(const BigUnsignedInteger &other)

Subtract another value in place.

Parameters:

other – The value to subtract.

Throws:

err::OverflowError – If other is larger than this value.

Returns:

This value after the subtraction.

BigUnsignedInteger operator*(const BigUnsignedInteger &other) const

Multiply by another value.

Parameters:

other – The factor.

Returns:

The exact product.

BigUnsignedInteger &operator*=(const BigUnsignedInteger &other)

Multiply by another value in place.

Parameters:

other – The factor.

Returns:

This value after the multiplication.

BigUnsignedInteger operator/(const BigUnsignedInteger &other) const

Divide by another value.

Parameters:

other – The divisor, which must not be zero.

Returns:

The quotient.

BigUnsignedInteger &operator/=(const BigUnsignedInteger &other)

Divide by another value in place.

Parameters:

other – The divisor, which must not be zero.

Returns:

This value after the division.

BigUnsignedInteger operator%(const BigUnsignedInteger &other) const

Calculate the remainder of a division.

Parameters:

other – The divisor, which must not be zero.

Returns:

The remainder.

BigUnsignedInteger &operator%=(const BigUnsignedInteger &other)

Store the remainder of a division in place.

Parameters:

other – The divisor, which must not be zero.

Returns:

This value after the modulo operation.

bool isZero() const noexcept

Test whether this value is zero.

bool isOne() const noexcept

Test whether this value is one.

template<NativeInteger T>
T cast() const

Cast this value to a native integer, clamping it to the target range.

Template Parameters:

T – The target native integer type.

Returns:

The converted value.

template<NativeInteger T>
T castOrThrow() const

Cast this value to a native integer without clamping.

Template Parameters:

T – The target native integer type.

Throws:

err::OverflowError – If this value cannot be represented by T.

Returns:

The converted value.

text::String toString() const

Convert this value to decimal text.

BigUnsignedInteger divideGetRemainder(const BigUnsignedInteger &divisor)

Divide this value in place and return the remainder.

Parameters:

divisor – The divisor, which must not be zero.

Returns:

The remainder of the division.

Public Static Functions

static std::optional<BigUnsignedInteger> fromString(const text::String &text)

Parse a complete decimal value.

Parameters:

text – The text to parse.

Returns:

The parsed value, or an empty optional for invalid text.

static BigUnsignedInteger fromStringOrThrow(const text::String &text)

Parse a complete decimal value.

Parameters:

text – The text to parse.

Throws:

err::ParseError – If text is not a valid unsigned decimal integer.

Returns:

The parsed value.

template<NativeInteger tValue, tValue tMinimum = std::numeric_limits<tValue>::min(), tValue tMaximum = std::numeric_limits<tValue>::max(), tValue tDefault = tMinimum>
class BoundedInteger

Integer value that is always bound to a fixed inclusive range.

Arithmetic saturates at the configured range bounds.

Subclassed by erbsland::time::impl::TimePart< tDerived, tValue, tMinimum, tMaximum, tDefault >

Public Types

using NativeValue = tValue

The native integer type.

using SaturatingValue = SaturatingInteger<NativeValue>

The internal saturating value type.

Public Functions

inline constexpr BoundedInteger() noexcept

Create the configured default value.

template<AnyIntegerType T>
inline explicit constexpr BoundedInteger(T value) noexcept

Create a value clamped to the configured range.

inline constexpr std::strong_ordering operator<=>(const BoundedInteger &other) const noexcept

Compare two clamped integers.

inline constexpr bool operator==(const BoundedInteger &other) const noexcept

Test if two clamped integers contain the same value.

inline BoundedInteger operator+(const BoundedInteger &other) const noexcept

Add another clamped integer with range saturation.

inline BoundedInteger &operator+=(const BoundedInteger &other) noexcept

Add another clamped integer in place with range saturation.

inline BoundedInteger operator-(const BoundedInteger &other) const noexcept

Subtract another clamped integer with range saturation.

inline BoundedInteger &operator-=(const BoundedInteger &other) noexcept

Subtract another clamped integer in place with range saturation.

template<AnyIntegerType T>
inline BoundedInteger operator+(T other) const noexcept

Add an integer operand with range saturation.

template<AnyIntegerType T>
inline BoundedInteger &operator+=(T other) noexcept

Add an integer operand in place with range saturation.

template<AnyIntegerType T>
inline BoundedInteger operator-(T other) const noexcept

Subtract an integer operand with range saturation.

template<AnyIntegerType T>
inline BoundedInteger &operator-=(T other) noexcept

Subtract an integer operand in place with range saturation.

inline BoundedInteger &operator++() noexcept

Increment with range saturation.

inline BoundedInteger operator++(int) noexcept

Increment with range saturation.

inline BoundedInteger &operator--() noexcept

Decrement with range saturation.

inline BoundedInteger operator--(int) noexcept

Decrement with range saturation.

template<AnyIntegerType T>
inline constexpr std::strong_ordering compare(T other) const noexcept

Compare with an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator==(T other) const noexcept

Test if this value equals an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator!=(T other) const noexcept

Test if this value differs from an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator<(T other) const noexcept

Test if this value is less than an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator<=(T other) const noexcept

Test if this value is less than or equal to an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator>(T other) const noexcept

Test if this value is greater than an integer operand.

template<AnyIntegerType T>
inline constexpr bool operator>=(T other) const noexcept

Test if this value is greater than or equal to an integer operand.

template<AnyIntegerType T>
inline BoundedInteger added(T other) const noexcept

Return this value plus other, clamped to the configured range.

template<AnyIntegerType T>
inline void add(T other) noexcept

Add other in place, clamped to the configured range.

template<AnyIntegerType T>
inline BoundedInteger subtracted(T other) const noexcept

Return this value minus other, clamped to the configured range.

template<AnyIntegerType T>
inline void subtract(T other) noexcept

Subtract other in place, clamped to the configured range.

inline BoundedInteger incremented() const noexcept

Return this value incremented by one, clamped to the configured range.

inline void increment() noexcept

Increment this value in place, clamped to the configured range.

inline BoundedInteger decremented() const noexcept

Return this value decremented by one, clamped to the configured range.

inline void decrement() noexcept

Decrement this value in place, clamped to the configured range.

inline constexpr bool isMinimum() const noexcept

Check if this value is the configured minimum.

inline constexpr bool isMaximum() const noexcept

Check if this value is the configured maximum.

inline constexpr NativeValue toRawValue() const noexcept

Return the raw native integer value.

inline constexpr SaturatingValue toValue() const noexcept

Return the value as a saturating integer.

Public Static Functions

static inline constexpr NativeValue minimumRawValue() noexcept

Return the configured minimum as a raw value.

static inline constexpr NativeValue maximumRawValue() noexcept

Return the configured maximum as a raw value.

static inline constexpr BoundedInteger minimum() noexcept

Return the configured minimum value.

static inline constexpr BoundedInteger maximum() noexcept

Return the configured maximum value.

static inline constexpr IntegerRange<NativeValue> range() noexcept

Return the range accepted by this type.

template<AnyIntegerType T>
static inline constexpr bool contains(T value) noexcept

Test if value is inside the configured range.

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::saturatingAddBounded(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> tResult

Add two same-size native integers and clamp the result to a custom bounded range.

See: Mathematical Types and Operations

Template Parameters:
  • tFirst – The first operand type.

  • tSecond – The second operand type.

  • tResult – The result and bounds type.

Parameters:
  • first – The first operand.

  • second – The second operand.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The mathematical sum clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::willAddBoundedSaturate(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> bool

Test if adding two same-size native integers would clamp to a custom bounded range.

Returns:

true if the mathematical sum is outside [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::saturatingSubtractBounded(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> tResult

Subtract two same-size native integers and clamp the result to a custom bounded range.

Returns:

The mathematical difference clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::willSubtractBoundedSaturate(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> bool

Test if subtracting two same-size native integers would clamp to a custom bounded range.

Returns:

true if the mathematical difference is outside [minimum, maximum].

template<NativeInteger tValue, NativeInteger tResult>
constexpr tResult erbsland::math::saturatingNegateBounded(tValue value, tResult minimum, tResult maximum) noexcept

Negate a same-size native integer and clamp the result to a custom bounded range.

Returns:

The mathematical negation clamped to [minimum, maximum].

template<NativeInteger tValue, NativeInteger tResult>
constexpr bool erbsland::math::willNegateBoundedSaturate(tValue value, tResult minimum, tResult maximum) noexcept

Test if negating a same-size native integer would clamp to a custom bounded range.

Returns:

true if the mathematical negation is outside [minimum, maximum].

template<NativeInteger tValue, NativeInteger tResult>
constexpr tResult erbsland::math::saturatingIncrementBounded(tValue value, tResult minimum, tResult maximum) noexcept

Increment a same-size native integer and clamp the result to a custom bounded range.

Returns:

The value plus one clamped to [minimum, maximum].

template<NativeInteger tValue, NativeInteger tResult>
constexpr tResult erbsland::math::saturatingDecrementBounded(tValue value, tResult minimum, tResult maximum) noexcept

Decrement a same-size native integer and clamp the result to a custom bounded range.

Returns:

The value minus one clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::saturatingMultiplyBounded(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> tResult

Multiply two native integers and clamp the result to a custom bounded range.

Returns:

The mathematical product clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::willMultiplyBoundedSaturate(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> bool

Test if multiplying two native integers would clamp to a custom bounded range.

Returns:

true if the mathematical product is outside [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::saturatingDivideBounded(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> tResult

Divide two native integers and clamp the result to a custom bounded range.

Returns:

The mathematical quotient clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::willDivideBoundedSaturate(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> bool

Test if dividing two native integers would clamp to a custom bounded range.

Returns:

true if the mathematical quotient is outside [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::saturatingModuloBounded(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> tResult

Calculate the modulo of two native integers and clamp the result to a custom bounded range.

Returns:

The mathematical remainder clamped to [minimum, maximum].

template<NativeInteger tFirst, NativeInteger tSecond, NativeInteger tResult>
constexpr auto erbsland::math::willModuloBoundedSaturate(tFirst first, tSecond second, tResult minimum, tResult maximum) noexcept -> bool

Test if a modulo operation between two native integers would clamp to a custom bounded range.

Returns:

true if the mathematical remainder is outside [minimum, maximum].

template<typename T>
concept UnsignedNativeInteger
#include <erbsland/math/IntegerBitOperations.hpp>

An unsigned native integer supported by the compiler-safe bit operations.

template<UnsignedNativeInteger T>
constexpr T erbsland::math::rotateLeft(const T value, const int amount) noexcept

Rotate an unsigned integer to the left.

Rotation amounts are reduced modulo the bit width; negative amounts rotate to the right.

Template Parameters:

T – An unsigned native integer type.

Parameters:
  • value – The value to rotate.

  • amount – The signed rotation amount.

Returns:

The rotated value.

template<UnsignedNativeInteger T>
constexpr T erbsland::math::rotateRight(const T value, const int amount) noexcept

Rotate an unsigned integer to the right.

Rotation amounts are reduced modulo the bit width; negative amounts rotate to the left.

Template Parameters:

T – An unsigned native integer type.

Parameters:
  • value – The value to rotate.

  • amount – The signed rotation amount.

Returns:

The rotated value.

template<UnsignedNativeInteger T>
constexpr T erbsland::math::loadBigEndian(const std::span<const std::byte, sizeof(T)> bytes) noexcept

Load an unsigned integer from bytes in big-endian order.

This function does not depend on alignment, aliasing, or native byte order.

Template Parameters:

T – An unsigned native integer type.

Parameters:

bytes – Exactly sizeof(T) bytes.

Returns:

The decoded integer.

template<UnsignedNativeInteger T>
constexpr T erbsland::math::loadLittleEndian(const std::span<const std::byte, sizeof(T)> bytes) noexcept

Load an unsigned integer from bytes in little-endian order.

This function does not depend on alignment, aliasing, or native byte order.

Template Parameters:

T – An unsigned native integer type.

Parameters:

bytes – Exactly sizeof(T) bytes.

Returns:

The decoded integer.

template<UnsignedNativeInteger T>
constexpr void erbsland::math::storeBigEndian(const T value, const std::span<std::byte, sizeof(T)> bytes) noexcept

Store an unsigned integer as bytes in big-endian order.

This function does not depend on alignment, aliasing, or native byte order.

Template Parameters:

T – An unsigned native integer type.

Parameters:
  • value – The integer to encode.

  • bytes – Exactly sizeof(T) writable bytes.

template<UnsignedNativeInteger T>
constexpr void erbsland::math::storeLittleEndian(const T value, const std::span<std::byte, sizeof(T)> bytes) noexcept

Store an unsigned integer as bytes in little-endian order.

This function does not depend on alignment, aliasing, or native byte order.

Template Parameters:

T – An unsigned native integer type.

Parameters:
  • value – The integer to encode.

  • bytes – Exactly sizeof(T) writable bytes.

template<AnyIntegerType T>
constexpr NativeIntegerOfT<T> erbsland::math::toNativeInteger(T value) noexcept

Convert an integer operand to its native integer value.

SaturatingInteger unwraps via toRawValue(). Native integers pass through unchanged.

Template Parameters:

T – The integer operand type.

Parameters:

value – The value to convert.

Returns:

The native integer representation.

template<AnyIntegerType T>
constexpr SaturatingInteger<NativeIntegerOfT<T>> erbsland::math::toSaturatingInteger(T value) noexcept

Convert an integer operand to a SaturatingInteger.

SaturatingInteger values pass through unchanged. Native integers are wrapped in a SaturatingInteger.

Template Parameters:

T – The integer operand type.

Parameters:

value – The value to convert.

Returns:

The value wrapped in a SaturatingInteger.

template<NativeInteger T>
constexpr bool erbsland::math::isNegativeValue(T value) noexcept

Test if any given integer is negative.

Always returns false for unsigned integers.

Template Parameters:

T – Any signed or unsigned integer type.

Parameters:

value – The value to test.

Returns:

true if the value is negative.

template<NativeInteger T>
constexpr std::make_unsigned_t<T> erbsland::math::toUnsignedAbsolute(T value) noexcept

Get the absolute value of an integer as an unsigned integer.

This helper avoids undefined behavior for the minimum value of signed integer types.

Template Parameters:

T – Any signed or unsigned integer type.

Parameters:

value – The value to convert.

Returns:

The absolute value represented as the matching unsigned integer type.

template<NativeInteger tFirst, NativeInteger tSecond>
constexpr std::strong_ordering erbsland::math::mixedIntegerCompare(tFirst first, tSecond second) noexcept

Compare two integer values of mixed native types safely.

Template Parameters:
  • tFirst – The type of first must be an integral type.

  • tSecond – The type of second must be an integral type.

Parameters:
  • first – The first value for comparison.

  • second – The second value for comparison.

Returns:

The result, how first compares to second. std::strong_ordering::less means first is smaller than second.

template<NativeInteger tFirst, NativeInteger tSecond>
constexpr std::make_unsigned_t<CompatibleNativeIntegerT<tFirst, tSecond>> erbsland::math::integerAbsoluteDifference(tFirst first, tSecond second) noexcept

Get the absolute difference between two mixed integers safely.

Template Parameters:
  • tFirst – The type of first must be an integral type.

  • tSecond – The type of second must be an integral type.

Parameters:
  • first – The first value.

  • second – The second value.

Returns:

The absolute difference between the two values. Always an unsigned integer that can represent all absolute-difference-values of both input types.

template<NativeInteger T>
constexpr T erbsland::math::toIntegerNormal(T value) noexcept

Normalize an integer value.

If the integer is negative, return -1, if it is zero, return zero if it is positive, return 1.

Template Parameters:

T – The type of the integer.

Parameters:

value – The value to normalize.

Returns:

The normalized value, 0, 1, or -1.

template<std::totally_ordered T>
constexpr void erbsland::math::orderMinimumMaximum(T &minimum, T &maximum) noexcept(noexcept(std::swap(minimum, maximum)))

Order two bounds in place.

If minimum is greater than maximum, the values are swapped.

Template Parameters:

T – The totally ordered bound type.

Parameters:
  • minimum – The lower bound after this call.

  • maximum – The upper bound after this call.

template<NativeInteger tValue>
class IntegerRange

Inclusive range for native integer values.

If constructed with reversed bounds, the bounds are ordered automatically.

Public Types

using Value = tValue

The integer type stored by this range.

Public Functions

constexpr IntegerRange() noexcept = default

Create the single-value range 0...0.

inline constexpr IntegerRange(Value minimum, Value maximum) noexcept

Create an inclusive range from minimum to maximum.

constexpr std::strong_ordering operator<=>(const IntegerRange &other) const noexcept = default

Compare two ranges by minimum first, then maximum.

template<AnyIntegerType T>
inline constexpr bool contains(T value) const noexcept

Test if this range contains value.

template<NativeInteger T>
inline constexpr bool contains(IntegerRange<T> range) const noexcept

Test if this range fully contains another range.

template<AnyIntegerType T>
inline constexpr Value clamped(T value) const noexcept

Return value clamped to this range.

template<NativeInteger T>
inline constexpr IntegerRange<T> cast() const noexcept

Cast this range to another native integer type with saturation.

inline constexpr Value minimum() const noexcept

Get the minimum value.

inline constexpr Value maximum() const noexcept

Get the maximum value.

template<NativeInteger tValue>
class SaturatingInteger

Integer wrapper with arithmetic that saturates at the limits of the native value type.

Arithmetic operators require matching signedness and return a saturating integer using the larger operand type. The named methods keep this type as result and also accept mixed signedness. Bitwise operations are not supported.

Public Types

using NativeValue = tValue

The wrapped native integer type.

using WrapCount = SaturatingInteger<std::int64_t>

The signed integer type used to report wrap counts.

Public Functions

constexpr SaturatingInteger() = default

Create a zero value.

template<AnyIntegerType tOther>
explicit constexpr SaturatingInteger(tOther value) noexcept

Create a saturating integer from another supported integer operand.

~SaturatingInteger() = default

Destroy this saturating integer.

SaturatingInteger(const SaturatingInteger&) = default

Copy a saturating integer.

SaturatingInteger(SaturatingInteger&&) = default

Move a saturating integer.

SaturatingInteger &operator=(const SaturatingInteger&) = default

Copy another saturating integer into this value.

SaturatingInteger &operator=(SaturatingInteger&&) = default

Move another saturating integer into this value.

template<AnyIntegerType T>
constexpr bool operator==(T other) const noexcept

Test if this value equals another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if both values compare equal.

template<AnyIntegerType T>
constexpr bool operator!=(T other) const noexcept

Test if this value differs from another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if the values do not compare equal.

template<AnyIntegerType T>
constexpr bool operator<(T other) const noexcept

Test if this value is less than another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if this value is less than other.

template<AnyIntegerType T>
constexpr bool operator<=(T other) const noexcept

Test if this value is less than or equal to another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if this value is less than or equal to other.

template<AnyIntegerType T>
constexpr bool operator>(T other) const noexcept

Test if this value is greater than another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if this value is greater than other.

template<AnyIntegerType T>
constexpr bool operator>=(T other) const noexcept

Test if this value is greater than or equal to another integer operand.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to compare.

Returns:

true if this value is greater than or equal to other.

SaturatingInteger &operator++() noexcept

Increment this value without exceeding the maximum representable value.

Returns:

This value after the increment.

SaturatingInteger operator++(int) noexcept

Increment this value without exceeding the maximum representable value.

Returns:

The value before the increment.

SaturatingInteger &operator--() noexcept

Decrement this value without exceeding the minimum representable value.

Returns:

This value after the decrement.

SaturatingInteger operator--(int) noexcept

Decrement this value without exceeding the minimum representable value.

Returns:

The value before the decrement.

template<AnyIntegerType T>
SaturatingInteger<CompatibleNativeIntegerT<NativeValue, NativeIntegerOfT<T>>> operator+(T other) const noexcept

Add another integer operand with saturation.

The operands must have compatible signedness; the result uses the larger native type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to add.

Returns:

The saturated sum.

template<AnyIntegerType T>
SaturatingInteger &operator+=(T other) noexcept

Add another integer operand and store the saturated result in this value.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to add.

Returns:

This value after the addition.

template<AnyIntegerType T>
SaturatingInteger<CompatibleNativeIntegerT<NativeValue, NativeIntegerOfT<T>>> operator-(T other) const noexcept

Subtract another integer operand with saturation.

The operands must have compatible signedness; the result uses the larger native type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to subtract.

Returns:

The saturated difference.

template<AnyIntegerType T>
SaturatingInteger &operator-=(T other) noexcept

Subtract another integer operand and store the saturated result in this value.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to subtract.

Returns:

This value after the subtraction.

template<AnyIntegerType T>
SaturatingInteger<CompatibleNativeIntegerT<NativeValue, NativeIntegerOfT<T>>> operator*(T other) const noexcept

Multiply by another integer operand with saturation.

The operands must have compatible signedness; the result uses the larger native type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The factor.

Returns:

The saturated product.

template<AnyIntegerType T>
SaturatingInteger &operator*=(T other) noexcept

Multiply by another integer operand and store the saturated result in this value.

Template Parameters:

T – The type of the other value.

Parameters:

other – The factor.

Returns:

This value after the multiplication.

template<AnyIntegerType T>
SaturatingInteger<CompatibleNativeIntegerT<NativeValue, NativeIntegerOfT<T>>> operator/(T other) const noexcept

Divide by another integer operand with saturation.

The operands must have compatible signedness; the result uses the larger native type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

The saturated quotient.

template<AnyIntegerType T>
SaturatingInteger &operator/=(T other) noexcept

Divide by another integer operand and store the saturated result in this value.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

This value after the division.

template<AnyIntegerType T>
SaturatingInteger<CompatibleNativeIntegerT<NativeValue, NativeIntegerOfT<T>>> operator%(T other) const noexcept

Apply modulo with another integer operand.

The operands must have compatible signedness; the result uses the larger native type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

The saturated remainder.

template<AnyIntegerType T>
SaturatingInteger &operator%=(T other) noexcept

Apply modulo with another integer operand and store the result in this value.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

This value after the modulo operation.

template<AnyIntegerType T>
SaturatingInteger added(T other) const noexcept

Add another integer operand and keep this type as the result type.

Unlike operator+, this method accepts mixed signedness and saturates to this native value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value of the operation.

Returns:

The result of the operation.

template<AnyIntegerType T>
SaturatingInteger subtracted(T other) const noexcept

Subtract another integer operand and keep this type as the result type.

template<AnyIntegerType T>
SaturatingInteger absoluteDifference(T other) const noexcept

Calculate the non-negative difference to another integer operand and keep this type as the result type.

The difference saturates to this native value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value of the operation.

Returns:

The saturated absolute difference.

template<AnyIntegerType T>
SaturatingInteger multiplied(T other) const noexcept

Multiply another integer operand and keep this type as the result type.

template<AnyIntegerType T>
SaturatingInteger divided(T other) const noexcept

Divide another integer operand and keep this type as the result type.

template<AnyIntegerType T>
SaturatingInteger modulo(T other) const noexcept

Calculate the modulo of another integer operand and keep this type as the result type.

template<AnyIntegerType T>
void add(T other) noexcept

Add another integer operand and store the saturated result in this value.

Unlike operator+=, this method accepts mixed signedness and cannot be chained accidentally.

Template Parameters:

T – The type of the other value.

Parameters:

other – The other value to perform the operation.

template<AnyIntegerType T>
void subtract(T other) noexcept

Subtract another integer operand and store the saturated result in this value.

template<AnyIntegerType T>
void multiply(T other) noexcept

Multiply another integer operand and store the saturated result in this value.

template<AnyIntegerType T>
void divide(T other) noexcept

Divide another integer operand and store the saturated result in this value.

template<AnyIntegerType T>
void applyModulo(T other) noexcept

Modulo with another integer operand and store the saturated result in this value.

template<AnyIntegerType T>
SaturatingInteger divideGetRemainder(T other) noexcept

Divide this value, store the quotient and return the remainder.

This mirrors std::div, but works with every supported integer operand and saturates to this type.

Template Parameters:

T – The type of the divider.

Parameters:

other – The divider.

Returns:

The remainder of the division.

template<AnyIntegerType T>
SaturatingInteger divideKeepRemainder(T other) noexcept

Divide this value, store the remainder and return the quotient.

This mirrors std::div, but works with every supported integer operand and saturates to this type.

Template Parameters:

T – The type of the divider.

Parameters:

other – The divider.

Returns:

The result of the division.

template<AnyIntegerType T>
SaturatingInteger raisedTo(T power) const noexcept

Raise this value to an integer power.

The implementation uses exponentiation by squaring and saturates once the result exceeds this type. A zero power always results in 1. Negative powers always result in 0.

Template Parameters:

T – The type of the power value.

Parameters:

power – The power value.

Returns:

The exponential value.

template<AnyIntegerType T>
bool wouldAddSaturate(T other) const noexcept

Test if adding another integer operand would saturate this value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to add.

Returns:

true if the addition would saturate.

template<AnyIntegerType T>
bool wouldSubtractSaturate(T other) const noexcept

Test if subtracting another integer operand would saturate this value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The value to subtract.

Returns:

true if the subtraction would saturate.

template<AnyIntegerType T>
bool wouldMultiplySaturate(T other) const noexcept

Test if multiplying by another integer operand would saturate this value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The factor.

Returns:

true if the multiplication would saturate.

template<AnyIntegerType T>
bool wouldDivideSaturate(T other) const noexcept

Test if dividing by another integer operand would saturate this value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

true if the division would saturate.

template<AnyIntegerType T>
bool wouldModuloSaturate(T other) const noexcept

Test if a modulo operation with another integer operand would saturate this value type.

Template Parameters:

T – The type of the other value.

Parameters:

other – The divisor.

Returns:

true if the modulo operation would saturate.

template<AnyIntegerType T>
constexpr SaturatingInteger<NativeIntegerOfT<T>> cast() const noexcept

Cast this value to another supported integer type with saturation.

Template Parameters:

T – The target type for the cast.

Returns:

The saturated casted value.

template<AnyIntegerType T>
constexpr SaturatingInteger<NativeIntegerOfT<T>> castOrThrow() const

Cast this value to another supported integer type.

Template Parameters:

T – The target type for the cast.

Throws:

err::OverflowError – if the value cannot be represented by the target type.

Returns:

The casted value.

inline constexpr NativeValue toRawValue() const noexcept

Convert this saturating integer to a regular integer value.

Returns:

The native integer.

constexpr std::size_t toSizeT() const noexcept

Convert this value to std::size_t with saturation.

Returns:

The saturated integer as std::size_t.

template<AnyIntegerType T>
constexpr std::strong_ordering compare(T value) const noexcept

Compare this value with another integer operand.

Template Parameters:

T – The type of the compared value.

Parameters:

value – The value to compare.

Returns:

The ordering of this value compared to value.

template<AnyIntegerType T>
constexpr void clamp(T minimum, T maximum) noexcept

Clamp this value to a native integer range.

If minimum > maximum, the behaviour is undefined. If minimum or maximum exceed the minimum/maximum value of the integer, they have no effect.

Template Parameters:

T – The type of the clamping integers.

Parameters:
  • minimum – The minimum value to clamp to.

  • maximum – The maximum value to clamp to.

template<NativeInteger T>
constexpr void clamp(IntegerRange<T> range) noexcept

Clamp this value to a native integer range.

Template Parameters:

T – The native range value type.

Parameters:

range – The range to clamp to.

template<AnyIntegerType T>
constexpr SaturatingInteger clamped(T minimum, T maximum) const noexcept

Return a new value clamped to a native integer range.

If minimum > maximum, the behaviour is undefined. If minimum or maximum exceed the minimum/maximum value of the integer, they have no effect.

Template Parameters:

T – The type of the clamping integers.

Parameters:
  • minimum – The minimum value to clamp to.

  • maximum – The maximum value to clamp to.

Returns:

The new clamped value.

template<NativeInteger T>
constexpr SaturatingInteger clamped(IntegerRange<T> range) const noexcept

Return a new value clamped to a native integer range.

Template Parameters:

T – The native range value type.

Parameters:

range – The range to clamp to.

Returns:

The new clamped value.

template<AnyIntegerType T>
void wrap(T minimum, T maximum) noexcept

Wrap this value to a native integer range.

Invalid direct bounds or a range outside this native type reset the value to zero.

Template Parameters:

T – The type of the range bounds.

Parameters:
  • minimum – The inclusive minimum value.

  • maximum – The inclusive maximum value.

template<NativeInteger T>
void wrap(IntegerRange<T> range) noexcept

Wrap this value to a native integer range.

A range outside this native type resets the value to zero.

Template Parameters:

T – The native range value type.

Parameters:

range – The wrap range.

template<AnyIntegerType T>
SaturatingInteger wrapped(T minimum, T maximum) const noexcept

Return this value wrapped to a native integer range.

Invalid direct bounds or a range outside this native type return zero.

Template Parameters:

T – The type of the range bounds.

Parameters:
  • minimum – The inclusive minimum value.

  • maximum – The inclusive maximum value.

Returns:

The wrapped value.

template<NativeInteger T>
SaturatingInteger wrapped(IntegerRange<T> range) const noexcept

Return this value wrapped to a native integer range.

A range outside this native type returns zero.

Template Parameters:

T – The native range value type.

Parameters:

range – The wrap range.

Returns:

The wrapped value.

template<AnyIntegerType T>
WrapCount wrapAndCount(T minimum, T maximum) noexcept

Wrap this value to a native integer range and return the signed wrap count.

Invalid direct bounds or a range outside this native type reset the value and return zero.

Template Parameters:

T – The type of the range bounds.

Parameters:
  • minimum – The inclusive minimum value.

  • maximum – The inclusive maximum value.

Returns:

The signed wrap count.

template<NativeInteger T>
WrapCount wrapAndCount(IntegerRange<T> range) noexcept

Wrap this value to a native integer range and return the signed wrap count.

A range outside this native type resets the value and returns zero.

Template Parameters:

T – The native range value type.

Parameters:

range – The wrap range.

Returns:

The signed wrap count.

template<AnyIntegerType T>
std::tuple<SaturatingInteger, WrapCount> wrappedAndCount(T minimum, T maximum) const noexcept

Return this value wrapped to a native integer range and the signed wrap count.

Invalid direct bounds or a range outside this native type return zero values.

Template Parameters:

T – The type of the range bounds.

Parameters:
  • minimum – The inclusive minimum value.

  • maximum – The inclusive maximum value.

Returns:

The wrapped value and signed wrap count.

template<NativeInteger T>
std::tuple<SaturatingInteger, WrapCount> wrappedAndCount(IntegerRange<T> range) const noexcept

Return this value wrapped to a native integer range and the signed wrap count.

A range outside this native type returns zero values.

Template Parameters:

T – The native range value type.

Parameters:

range – The wrap range.

Returns:

The wrapped value and signed wrap count.

inline constexpr bool isZero() const noexcept

Check if this value is zero.

Returns:

true if this value is zero.

inline constexpr bool isOne() const noexcept

Check if this value is one.

Returns:

true if this value is one.

constexpr bool isNegative() const noexcept

Check if this value is negative.

Returns:

true if this value is negative.

inline constexpr bool isMinimum() const noexcept

Check if this value is equal to the minimum value.

Returns:

true if this value is equal to the minimum value.

inline constexpr bool isMaximum() const noexcept

Check if this value is equal to the maximum value.

Returns:

true if this value is equal to the maximum value.

constexpr SaturatingInteger toAbsolute() const noexcept

Get the absolute value saturated to this type.

Note

For signed integers, the minimum value saturates to the maximum positive value.

Returns:

The absolute value.

constexpr SaturatingInteger<std::make_unsigned_t<NativeValue>> toUnsignedAbsolute() const noexcept

Get the absolute value using the matching unsigned integer type.

Returns:

The absolute value.

constexpr SaturatingInteger negated() const noexcept

Get the negated value.

Unsigned values saturate to zero. The minimum signed value saturates to the maximum positive value.

Returns:

The negated value.

void negate() noexcept

Negate this value in place.

Unsigned values saturate to zero. The minimum signed value saturates to the maximum positive value.

Public Static Functions

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static SaturatingInteger fromAddition(tFirst first, tSecond second) noexcept

Add two integer operands and saturate the result to this type.

Template Parameters:
  • tFirst – The first operand type.

  • tSecond – The second operand type.

Parameters:
  • first – The first value.

  • second – The second value.

Returns:

The saturated result using this type.

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static SaturatingInteger fromSubtraction(tFirst first, tSecond second) noexcept

Subtract two integer operands and saturate the result to this type.

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static SaturatingInteger fromMultiplication(tFirst first, tSecond second) noexcept

Multiply two integer operands and saturate the result to this type.

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static SaturatingInteger fromDivision(tFirst first, tSecond second) noexcept

Divide two integer operands and saturate the result to this type.

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static SaturatingInteger fromModulo(tFirst first, tSecond second) noexcept

Apply modulo to two integer operands and saturate the result to this type.

template<AnyIntegerType tFirst, AnyIntegerType tSecond>
static std::tuple<SaturatingInteger, SaturatingInteger> fromDivisionWithRemainder(tFirst first, tSecond second) noexcept

Divide two operands and return quotient and remainder.

Template Parameters:
  • tFirst – The dividend type and tuple value type.

  • tSecond – The divisor type.

Parameters:
  • first – The value that is divided.

  • second – The divider.

Returns:

A tuple with quotient first and remainder second.

static inline constexpr SaturatingInteger maximum() noexcept

Get the maximum representable value.

Returns:

The maximum value for this saturating integer type.

static inline constexpr SaturatingInteger minimum() noexcept

Get the minimum representable value.

Returns:

The minimum value for this saturating integer type.

static inline constexpr IntegerRange<NativeValue> range() noexcept

Get the range of all representable values.

Returns:

The native integer range for this type.

static inline constexpr SaturatingInteger zero() noexcept

Get the zero value.

Returns:

A zero value for this saturating integer type.

static inline constexpr std::size_t bitCount() noexcept

Get the number of bits of this integer.

Returns:

The number of bits in the native value type.

static inline constexpr bool isSigned() noexcept

Test if this is a signed integer.

Returns:

true if the native value type is signed.

Friends

inline friend void swap(SaturatingInteger &first, SaturatingInteger &second) noexcept

Efficiently swap two saturating integers.

using erbsland::math::SatInt8 = SaturatingInteger<std::int8_t>

A saturating signed integer with 8bit size.

using erbsland::math::SatInt16 = SaturatingInteger<std::int16_t>

A saturating signed integer with 16bit size.

using erbsland::math::SatInt32 = SaturatingInteger<std::int32_t>

A saturating signed integer with 32bit size.

using erbsland::math::SatInt64 = SaturatingInteger<std::int64_t>

A saturating signed integer with 64bit size.

using erbsland::math::SatUInt8 = SaturatingInteger<std::uint8_t>

A saturating unsigned integer with 8bit size.

using erbsland::math::SatUInt16 = SaturatingInteger<std::uint16_t>

A saturating unsigned integer with 16bit size.

using erbsland::math::SatUInt32 = SaturatingInteger<std::uint32_t>

A saturating unsigned integer with 32bit size.

using erbsland::math::SatUInt64 = SaturatingInteger<std::uint64_t>

A saturating unsigned integer with 64bit size.

template<typename T>
struct IsSaturatingInteger : public std::false_type

Test if a type is SaturatingInteger.

template<NativeInteger T>
T erbsland::math::saturatingAdd(T first, T second) noexcept

Add two integers but limit the result to the maximum possible values.

Template Parameters:

T – Any signed or unsigned integer type

Parameters:
  • first – The first value.

  • second – The second value.

Returns:

The addition result, limited to the used type.

template<NativeInteger T>
T erbsland::math::saturatingSubtract(T first, T second) noexcept

Subtract two integers but limit the result to the maximum possible values.

Template Parameters:

T – Any signed or unsigned integer type

Parameters:
  • first – The first value.

  • second – The second value.

Returns:

The subtraction result, limited to the used type.

template<NativeInteger T>
T erbsland::math::saturatingMultiply(T first, T second) noexcept

Multiply two integers but limit the result to the maximum possible values.

Template Parameters:

T – Any signed or unsigned integer type.

Parameters:
  • first – The first multiplier.

  • second – The second multiplier.

Returns:

The product, limited to the used type.

template<NativeInteger T>
T erbsland::math::saturatingDivide(T first, T second) noexcept

Divide integers but limit the result to the maximum possible values.

Template Parameters:

T – Any signed or unsigned integer type.

Parameters:
  • first – dividend.

  • second – divisor.

Returns:

The result of the division, limited to the used type.

template<NativeInteger T>
T erbsland::math::saturatingModulo(T first, T second) noexcept

Get the remainder of a division between integers but limit the result to the maximum possible values.

Template Parameters:

T – Any signed or unsigned integer type.

Parameters:
  • first – dividend.

  • second – divisor.

Returns:

The result of the division, limited to the used type.

template<NativeInteger T>
bool erbsland::math::willAddOverflow(T first, T second) noexcept

Test if an addition will overflow.

Template Parameters:

T – The type for the operands.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger T>
bool erbsland::math::willSubtractOverflow(T first, T second) noexcept

Test if a subtraction will overflow.

Template Parameters:

T – The type for the operands.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger T>
bool erbsland::math::willMultiplyOverflow(T first, T second) noexcept

Test if a multiplication will overflow.

Template Parameters:

T – The type for the operands.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger T>
bool erbsland::math::willDivideOverflow(T first, T second) noexcept

Test if a division will overflow.

Template Parameters:

T – The type for the operands.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger T>
bool erbsland::math::willModuloOverflow(T first, T second) noexcept

Test if a modulo will overflow.

Template Parameters:

T – The type for the operands.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tTargetType, NativeInteger tSourceType>
constexpr tTargetType erbsland::math::saturatingCast(tSourceType value) noexcept

Convert an integer type into another one, but make sure the result will not overflow.

See: Saturating Casts

Template Parameters:
  • tTargetType – The target type for the cast.

  • tSourceType – The source type to cast.

Parameters:

value – The source value to cast.

Returns:

A value as target type.

template<NativeInteger tTargetType, NativeInteger tSourceType>
constexpr bool erbsland::math::willCastOverflow(tSourceType value) noexcept

Check if a native cast would overflow.

Template Parameters:
  • tTargetType – The target type for the cast.

  • tSourceType – The source type to cast.

Parameters:

value – The source value to check for an overflow.

Returns:

true if a native cast cannot represent value in the target type without clipping.

template<NativeInteger T>
void erbsland::math::saturatingIncrement(T &value) noexcept

Increment a value but never overflow.

Template Parameters:

T – The type of the value.

Parameters:

value – The value to increment.

template<NativeInteger T>
void erbsland::math::saturatingDecrement(T &value) noexcept

Increment a value but never overflow.

Template Parameters:

T – The type of the value.

Parameters:

value – The value to decrement.

template<NativeInteger tFirst, NativeInteger tSecond>
tFirst erbsland::math::saturatingAdd(tFirst first, tSecond second) noexcept

Saturated add with any integer type.

See: Mixed Types

Template Parameters:
  • tFirst – The target type for the operation.

  • tSecond – The type of the second summand.

Parameters:
  • first – The value to change.

  • second – The value to add.

Returns:

The result.

template<NativeInteger tFirst, NativeInteger tSecond>
tFirst erbsland::math::saturatingSubtract(tFirst first, tSecond second) noexcept

Saturated subtract with any integer type.

See: Mixed Types

Template Parameters:
  • tFirst – The target type for the operation.

  • tSecond – The type of the subtrahend.

Parameters:
  • first – The value to change.

  • second – The value to subtract.

Returns:

The result.

template<NativeInteger tFirst, NativeInteger tSecond>
tFirst erbsland::math::saturatingMultiply(tFirst first, tSecond second) noexcept

Saturated multiply with any compatible integer type.

See: Mixed Types

Template Parameters:
  • tFirst – The target type for the operation.

  • tSecond – The type of the factor.

Parameters:
  • first – The value to change.

  • second – The factor.

Returns:

The result.

template<NativeInteger tFirst, NativeInteger tSecond>
tFirst erbsland::math::saturatingDivide(tFirst first, tSecond second) noexcept

Saturated division with any compatible integer type.

See: Mixed Types

Template Parameters:
  • tFirst – The target type for the operation.

  • tSecond – The type of the divisor.

Parameters:
  • first – The value to change.

  • second – The divisor.

Returns:

The result.

template<NativeInteger tFirst, NativeInteger tSecond>
tFirst erbsland::math::saturatingModulo(tFirst first, tSecond second) noexcept

Saturated modulo with any compatible integer type.

See: Mixed Types

Template Parameters:
  • tFirst – The target type for the operation.

  • tSecond – The type of the divisor.

Parameters:
  • first – The value to change.

  • second – The divisor.

Returns:

The result.

template<NativeInteger tFirst, NativeInteger tSecond>
bool erbsland::math::willAddOverflow(tFirst first, tSecond second) noexcept

Test if an addition will overflow.

Template Parameters:
  • tFirst – The target type of the operation to test for the overflow.

  • tSecond – Operator type with no influence to the result type.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tFirst, NativeInteger tSecond>
bool erbsland::math::willSubtractOverflow(tFirst first, tSecond second) noexcept

Test if a subtraction will overflow.

Template Parameters:
  • tFirst – The target type of the operation to test for the overflow.

  • tSecond – Operator type with no influence to the result type.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tFirst, NativeInteger tSecond>
bool erbsland::math::willMultiplyOverflow(tFirst first, tSecond second) noexcept

Test if a multiplication will overflow.

Template Parameters:
  • tFirst – The target type of the operation to test for the overflow.

  • tSecond – Operator type with no influence to the result type.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tFirst, NativeInteger tSecond>
bool erbsland::math::willDivideOverflow(tFirst first, tSecond second) noexcept

Test if a division will overflow.

Template Parameters:
  • tFirst – The target type of the operation to test for the overflow.

  • tSecond – Operator type with no influence to the result type.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tFirst, NativeInteger tSecond>
bool erbsland::math::willModuloOverflow(tFirst first, tSecond second) noexcept

Test if a modulo operation will overflow.

Template Parameters:
  • tFirst – The target type of the operation to test for the overflow.

  • tSecond – Operator type with no influence to the result type.

Parameters:
  • first – The first value of the operation to test.

  • second – The second value of the operation to test.

Returns:

true if an overflow will occur, false otherwise.

template<NativeInteger tValue>
class SignedMagnitude

A same-width integer value represented as sign and unsigned magnitude.

See: Mathematical Types and Operations

Template Parameters:

tValue – The native integer type whose unsigned counterpart is used for the magnitude.

Public Types

using Value = NativeIntegerOfT<tValue>

The native integer type this signed-magnitude value is based on.

using Unsigned = std::make_unsigned_t<Value>

The unsigned type used to store the magnitude.

Public Functions

constexpr SignedMagnitude() noexcept = default

Create a zero value.

inline constexpr SignedMagnitude(bool negative, Unsigned magnitude) noexcept

Create a value from a sign and magnitude.

A zero magnitude is always normalized to a positive value.

Parameters:
  • negative – Set to true to create a negative value.

  • magnitude – The absolute magnitude.

template<AnyIntegerType tSource>
inline explicit constexpr SignedMagnitude(tSource value) noexcept

Create a signed-magnitude value from a same-width integer operand.

Signed negative input uses toUnsignedAbsolute() so the signed minimum value is converted safely. Unsigned input is treated as a positive magnitude.

Template Parameters:

tSource – The source integer type. It must have the same byte width as Value.

Parameters:

value – The integer operand to represent.

inline constexpr std::strong_ordering operator<=>(const SignedMagnitude &other) const noexcept

Compare two signed-magnitude values mathematically.

Negative magnitudes are ordered in reverse magnitude order, so -2 < -1 < 0 < 1 < 2.

Parameters:

other – The other value to compare with this value.

Returns:

The ordering of this value compared with other.

inline constexpr bool isNegative() const noexcept

Test if this value is negative.

Returns:

true if this value is smaller than zero.

inline constexpr bool isZero() const noexcept

Test if this value is zero.

Returns:

true if the magnitude is zero.

inline constexpr Unsigned magnitude() const noexcept

Get the unsigned magnitude.

Returns:

The absolute magnitude of this value.

inline constexpr SignedMagnitude negated() const noexcept

Return this value with the sign changed.

Zero remains positive after negation.

Returns:

The negated signed-magnitude value.

inline constexpr bool wouldSaturate(Value minimum, Value maximum) const noexcept

Test if this value is outside a bounded native result range.

The bounds must form a valid range. They are converted into the same sign/magnitude representation before comparison, so signed and unsigned result domains share the same code path.

Parameters:
  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

true if this value is outside [minimum, maximum].

inline constexpr Value toSaturatingValue(Value minimum, Value maximum) const noexcept

Convert this value into a bounded native result type.

The conversion clamps to the explicit bounds before converting back into Value. This keeps signed-minimum magnitudes and unsigned magnitudes above a signed maximum well-defined in constant expressions.

Parameters:
  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The native value clamped to [minimum, maximum].

inline constexpr auto saturatingAddBounded(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> Value

Add another signed-magnitude value and clamp the result into a bounded native result type.

Equal-sign magnitude overflow means the mathematical result is outside the representable sign/magnitude domain, so the result immediately clamps to the bound for that sign.

Parameters:
  • other – The value to add to this value.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The mathematical sum clamped to [minimum, maximum].

inline constexpr auto wouldAddBoundedSaturate(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> bool

Test if adding another signed-magnitude value would clamp to a bounded native result type.

Parameters:
  • other – The value to add to this value.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

true if the mathematical sum is outside [minimum, maximum].

inline constexpr auto saturatingMultiplyBounded(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> Value

Multiply by another signed-magnitude value and clamp the result into a bounded native result type.

Parameters:
  • other – The value to multiply this value with.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The mathematical product clamped to [minimum, maximum].

inline constexpr auto wouldMultiplyBoundedSaturate(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> bool

Test if multiplying another signed-magnitude value would clamp to a bounded native result type.

Parameters:
  • other – The value to multiply this value with.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

true if the mathematical product is outside [minimum, maximum].

inline constexpr auto saturatingDivideBounded(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> Value

Divide by another signed-magnitude value and clamp the result into a bounded native result type.

Parameters:
  • other – The divisor.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The mathematical quotient clamped to [minimum, maximum].

inline constexpr auto wouldDivideBoundedSaturate(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> bool

Test if dividing by another signed-magnitude value would clamp to a bounded native result type.

Parameters:
  • other – The divisor.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

true if the mathematical quotient is outside [minimum, maximum].

inline constexpr auto saturatingModuloBounded(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> Value

Calculate the modulo with another signed-magnitude value and clamp the result into a bounded native result type.

Parameters:
  • other – The divisor.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

The mathematical remainder clamped to [minimum, maximum].

inline constexpr auto wouldModuloBoundedSaturate(const SignedMagnitude &other, Value minimum, Value maximum) const noexcept -> bool

Test if modulo with another signed-magnitude value would clamp to a bounded native result type.

Parameters:
  • other – The divisor.

  • minimum – The smallest allowed result value.

  • maximum – The largest allowed result value.

Returns:

true if the mathematical remainder is outside [minimum, maximum].

Public Static Functions

static inline constexpr SignedMagnitude fromSignAndMagnitude(bool negative, Unsigned magnitude) noexcept

Create a value from a sign and magnitude.

This factory mirrors the sign/magnitude constructor and can make call sites easier to read when the arguments are computed expressions.

Parameters:
  • negative – Set to true to create a negative value.

  • magnitude – The absolute magnitude.

Returns:

The normalized signed-magnitude value.

template<AnyIntegerType tSource>
static inline constexpr SignedMagnitude fromValue(tSource value) noexcept

Create a signed-magnitude value from a same-width integer operand.

Template Parameters:

tSource – The source integer type. It must have the same byte width as Value.

Parameters:

value – The integer operand to represent.

Returns:

The value represented as sign and unsigned magnitude.