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_typewhenTis aSaturatingInteger<NativeInteger>, andstd::false_typeotherwise.
Concept
SaturatingIntegerType<T>A concept that is satisfied when
Tis aSaturatingIntegertype. This is a convenience wrapper aroundIsSaturatingInteger.
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.
-
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
textis 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.
-
BigInteger() = default
-
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
valueis 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
otheris 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
otheris 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.
-
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
textis not a valid unsigned decimal integer.- Returns:
The parsed value.
-
BigUnsignedInteger() = default
-
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 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
otherin 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
otherin 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.
-
using SaturatingValue = SaturatingInteger<NativeValue>
-
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:
trueif 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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.
SaturatingIntegerunwraps viatoRawValue(). 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.SaturatingIntegervalues pass through unchanged. Native integers are wrapped in aSaturatingInteger.- 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:
trueif 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
firstmust be an integral type.tSecond – The type of
secondmust be an integral type.
- Parameters:
first – The first value for comparison.
second – The second value for comparison.
- Returns:
The result, how
firstcompares tosecond.std::strong_ordering::lessmeansfirstis smaller thansecond.
-
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
firstmust be an integral type.tSecond – The type of
secondmust 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
minimumis greater thanmaximum, 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 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
minimumtomaximum.
-
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
valueclamped to this range.
-
template<NativeInteger T>
inline constexpr IntegerRange<T> cast() const noexcept Cast this range to another native integer type with saturation.
-
constexpr IntegerRange() noexcept = default
-
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 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:
trueif 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:
trueif 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:
trueif this value is less thanother.
-
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:
trueif this value is less than or equal toother.
-
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:
trueif this value is greater thanother.
-
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:
trueif this value is greater than or equal toother.
-
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 in0.- 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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_twith 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. Ifminimumormaximumexceed 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. Ifminimumormaximumexceed 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:
trueif this value is zero.
-
inline constexpr bool isOne() const noexcept
Check if this value is one.
- Returns:
trueif this value is one.
-
constexpr bool isNegative() const noexcept
Check if this value is negative.
- Returns:
trueif this value is negative.
-
inline constexpr bool isMinimum() const noexcept
Check if this value is equal to the minimum value.
- Returns:
trueif 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:
trueif 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:
trueif the native value type is signed.
Friends
-
inline friend void swap(SaturatingInteger &first, SaturatingInteger &second) noexcept
Efficiently swap two saturating integers.
-
using WrapCount = SaturatingInteger<std::int64_t>
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif a native cast cannot representvaluein 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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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:
trueif an overflow will occur,falseotherwise.
-
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
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
trueto 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:
trueif this value is smaller than zero.
-
inline constexpr bool isZero() const noexcept
Test if this value is zero.
- Returns:
trueif 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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:
trueif 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
trueto 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.