PhysicsBasedAnimationToolkit 0.0.10
Cross-platform C++20 library of algorithms and data structures commonly used in computer graphics research on physically-based simulation.
Loading...
Searching...
No Matches
IntegerArithmeticChecks.h
Go to the documentation of this file.
1
10
11#ifndef PBAT_MATH_INTEGER_ARITHMETIC_CHECKS_H
12#define PBAT_MATH_INTEGER_ARITHMETIC_CHECKS_H
13
14#include <concepts>
15#include <limits>
16#include <stdexcept>
17
18namespace pbat {
19namespace math {
20
29template <std::integral Integer>
30bool AddOverflows(Integer a, Integer b)
31{
32 if (a == 0 || b == 0)
33 return false;
34
35 auto constexpr max = std::numeric_limits<Integer>::max();
36 auto constexpr min = std::numeric_limits<Integer>::lowest();
37 if (a < 0 && b < 0)
38 {
39 // adding negative numbers may underflow, i.e. a+b < min
40 return a < (min - b);
41 }
42 if (a > 0 && b > 0)
43 {
44 // a+b > max <=> overflow
45 return a > (max - b);
46 }
47 return false;
48}
49
58template <std::integral Integer>
59bool MultiplyOverflows(Integer a, Integer b)
60{
61 if (a == 0 or b == 0)
62 return false;
63
64 auto constexpr max = std::numeric_limits<Integer>::max();
65 auto constexpr min = std::numeric_limits<Integer>::lowest();
66 bool const bSameSign = (a > 0 && b > 0) or (a < 0 && b < 0);
67 if (bSameSign)
68 {
69 // multiplying 2 same-sign numbers may overflow
70 // |a|*|b| > max <=> overflow
71 return std::abs(a) > std::abs(max / b);
72 }
73 else
74 {
75 // multiplying different sign numbers may underflow
76 // -|a|*|b| < min <=> underflow
77 return -std::abs(a) < (min / std::abs(b));
78 }
79}
80
88template <std::integral Integer>
89bool NegationOverflows(Integer a)
90{
91 auto constexpr max = std::numeric_limits<Integer>::max();
92 if constexpr (std::is_signed_v<Integer>)
93 {
94 // Signed integer values are in the range [-2^{n-1}+1, 2^{n-1}],
95 // hence only 2^{n-1} cannot be negated and held in the signed integer.
96 return a == max;
97 }
98 else
99 {
100 // All unsigned integers are positive except 0, hence negating anything > 0 is negative and
101 // cannot be represented by an unsigned type.
102 return a > 0;
103 }
104}
105
110template <std::integral Integer>
112{
114
120 Integer& operator*() { return value; }
126 Integer const& operator*() const { return value; }
133 {
135 throw std::overflow_error("Negation overflow");
136 return SelfType{-value};
137 }
138
145 {
146 if (AddOverflows(value, rhs.value))
147 throw std::overflow_error("Addition overflow");
148 return SelfType{value + rhs.value};
149 }
150
157 {
158 if (MultiplyOverflows(value, rhs.value))
159 throw std::overflow_error("Multiplication overflow");
160 return SelfType{value * rhs.value};
161 }
162
168 SelfType operator-(SelfType rhs) const { return (*this) + -rhs; }
175 SelfType operator/(SelfType rhs) const { return SelfType{value / rhs.value}; }
182 template <std::integral OtherInteger>
183 SelfType operator/(OtherInteger rhs) const
184 {
185 return SelfType{this->value / rhs};
186 }
187
190 operator Integer() const { return value; }
191
192 Integer value;
193};
194
195} // namespace math
196} // namespace pbat
197
198#endif // PBAT_MATH_INTEGER_ARITHMETIC_CHECKS_H
Math related functionality.
Definition Concepts.h:19
bool NegationOverflows(Integer a)
Checks if the operation is not in the range of values representable by the type of Integer.
Definition IntegerArithmeticChecks.h:89
bool MultiplyOverflows(Integer a, Integer b)
Checks if the operation is not in the range of values representable by the type of Integer.
Definition IntegerArithmeticChecks.h:59
bool AddOverflows(Integer a, Integer b)
Checks if the operation is not in the range of values representable by the type Integer.
Definition IntegerArithmeticChecks.h:30
The main namespace of the library.
Definition Aliases.h:15
Wrapper around integer types that throws when integer overflow is detected.
Definition IntegerArithmeticChecks.h:112
SelfType operator*(SelfType rhs) const
Multiplication operator.
Definition IntegerArithmeticChecks.h:156
SelfType operator/(OtherInteger rhs) const
Division operator.
Definition IntegerArithmeticChecks.h:183
SelfType operator+(SelfType rhs) const
Addition operator.
Definition IntegerArithmeticChecks.h:144
Integer const & operator*() const
Const dereference operator.
Definition IntegerArithmeticChecks.h:126
OverflowChecked< Integer > SelfType
Instance type.
Definition IntegerArithmeticChecks.h:113
Integer value
Underlying integer value.
Definition IntegerArithmeticChecks.h:192
Integer & operator*()
Dereference operator.
Definition IntegerArithmeticChecks.h:120
SelfType operator-(SelfType rhs) const
Subtraction operator.
Definition IntegerArithmeticChecks.h:168
SelfType operator/(SelfType rhs) const
Division operator.
Definition IntegerArithmeticChecks.h:175
SelfType operator-() const
Negation operator.
Definition IntegerArithmeticChecks.h:132