pw_numeric#
Efficient mathematical utilities for embedded
Stable C++
pw_numeric
is a collection of mathematical utilities optimized for embedded
systems.
What belongs in this module?
Any standalone mathematical, numerical, or statisitical utilities that are
optimized for embedded belong in pw_numeric
. This encompasses a broad area,
but since the C++ standard library provides many mathematical utilities already,
this module is not anticipated to be too large. If the module does grow
substantially, some features may be moved to other modules (e.g.
pw_statistics
).
What does NOT belong in this module?
Features available in the C++ standard library (
<cmath>
,<numeric>
,<bit>
, etc.) should not be duplicated.Pseudo-random number generation belongs in pw_random.
Data integrity checking belongs in pw_checksum.
Bit / byte manipulation belong in pw_bytes.
C++ API reference#
pw_numeric/checked_arithmetic.h#
-
template<typename T, typename A, typename B>
constexpr std::optional<T> pw::CheckedAdd(A a, B b)# Adds two numbers, checking for overflow.
Note
The template argument must be provided, e.g.
pw::CheckedAdd<uint32_t>(...)
.- Template Parameters:
T – The type of the result, which is checked for overflow.
A – The type of the first addend,
a
.B – The type of the second addend,
b
.
- Parameters:
a – [in] The first addend.
b – [in] The second addend.
- Returns:
The sum (
a + b
) if addition was successful, ornullopt
if the addition would overflow.
-
template<typename T, typename Inc>
constexpr bool pw::CheckedIncrement(T &base, Inc inc)# Increments a variable by some amount.
- Template Parameters:
T – The type of the variable to be incremented.
Inc – The type of the variable to add.
- Parameters:
base – [in] The variable to be incremented.
inc – [in] The number to add to
base
.
- Returns:
True if the addition was successful and
base
was incremented (base += inc
); False if the addition would overflow andbase
is unmodified.
-
template<typename T, typename A, typename B>
constexpr std::optional<T> pw::CheckedSub(A a, B b)# Subtracts two numbers, checking for overflow.
Note
The template argument must be provided, e.g.
pw::CheckedSub<uint32_t>(...)
.- Template Parameters:
T – The type of the result, which is checked for overflow.
A – The type of the minuend,
a
.B – The type of the subtrahend,
b
.
- Parameters:
a – [in] The minuend (the number from which
b
is subtracted).b – [in] The subtrahend (the number subtracted from
a
).
- Returns:
The difference (
a - b
) if subtraction was successful, ornullopt
if the subtraction would overflow.
-
template<typename T, typename Dec>
constexpr bool pw::CheckedDecrement(T &base, Dec dec)# Decrements a variable by some amount.
- Template Parameters:
T – The type of the variable to be decremented.
Dec – The type of the variable to subtract.
- Parameters:
base – [in] The variable to be decremented.
inc – [in] The number to subtract from
base
.
- Returns:
True if the subtraction was successful and
base
was decremented (base -= inc
); False if the subtraction would overflow andbase
is unmodified.
-
template<typename T, typename A, typename B>
constexpr std::optional<T> pw::CheckedMul(A a, B b)# Multiplies two numbers, checking for overflow.
Note
The template argument must be provided, e.g.
pw::CheckedMul<uint32_t>(...)
.- Template Parameters:
T – The type of the result, which is checked for overflow.
A – The type of the first factor,
a
.B – The type of the second factor,
b
.
- Parameters:
a – [in] The first factor.
b – [in] The second factor.
- Returns:
The product (
a * b
) if multiplication was successful, ornullopt
if the multiplication would overflow.
pw_numeric/integer_division.h#
-
template<typename T>
constexpr T pw::IntegerDivisionRoundNearest(T dividend, T divisor)# Performs integer division and rounds to the nearest integer. Gives the same result as
std::round(static_cast<double>(dividend) / static_cast<double>(divisor))
, but requires no floating point operations and isconstexpr
.Warning
signed
orunsigned
int
,long
, orlong long
operands overflow if:the quotient is positive and
dividend + divisor/2
overflows, orthe quotient is negative and
dividend - divisor/2
overflows.
To avoid overflow, do not use this function with very large operands, or cast
int
orlong
to a larger type first. Overflow cannot occur with types smaller thanint
because C++ implicitly converts them toint
.