[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 7258e4ae 05/10: Establish and test explicit p
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 7258e4ae 05/10: Establish and test explicit postconditions |
Date: |
Mon, 20 Jun 2022 19:16:21 -0400 (EDT) |
branch: master
commit 7258e4ae43cbf46e96a28a401d798f75db7ddb3e
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Establish and test explicit postconditions
Notably, specified the return type explicitly.
---
math_functions.hpp | 31 ++++++++++++++++++++++++-------
math_functions_test.cpp | 10 ++++++++--
2 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/math_functions.hpp b/math_functions.hpp
index 372cf74e..56ade0eb 100644
--- a/math_functions.hpp
+++ b/math_functions.hpp
@@ -162,20 +162,37 @@ T signum(T t)
return (0 == t) ? 0 : std::signbit(t) ? -1 : 1;
}
-/// Unsigned |signed value|. Needed because std::abs(INT_MIN) is UB.
+/// (Unsigned) absolute value of a signed integer.
+///
+/// Returns the absolute value of a signed integer, as a value of the
+/// corresponding unsigned type. Notably, the additive inverse of a
+/// negative integer is this absolute value.
+///
+/// Motivation: Attempting to take the absolute value of INT_MIN
+/// directly, as "std::abs(INT_MIN)", entails undefined behavior.
+/// So does attempting to take the additive inverse of INT_MIN by
+/// direct negation, as "-INT_MIN".
///
/// Asserts that both integer types have no padding, to rule out the
/// UINT_MAX == INT_MAX == -(INT_MIN+1)
/// case that Daniel Fischer points out somewhere on the web.
///
-/// The cast on the last line may appear superfluous, but it is not:
-/// unary '-' performs integral promotion on its operand and returns a
-/// result of the promoted type, which is (signed) 'int' if type T is
-/// narrower than 'int'. Without this cast, gcc would issue a warning
-/// in the accompanying unit test.
+/// Postconditions: for u = u_abs(t),
+/// - u is of an unsigned type
+/// - sizeof u == sizeof t
+/// and, if t is negative, then
+/// - 0 == t + u == u + t [for t < 0; incidentally, also for 0 == t]
+///
+/// If the cast on the last line is removed, then unary '-' performs
+/// integral promotion on its operand and returns a result of the
+/// promoted type, which is (signed) 'int' if type T is narrower than
+/// 'int', so the conditional operator returns a result of that type,
+/// which the function implicitly casts to its (narrower) return type.
+/// Thus, the cast has no actual effect; it serves only to clarify the
+/// intention.
template<typename T>
-constexpr auto u_abs(T t)
+constexpr std::make_unsigned_t<T> u_abs(T t)
{
static_assert(std::is_integral_v<T>);
static_assert(std::is_signed_v<T>);
diff --git a/math_functions_test.cpp b/math_functions_test.cpp
index cf561463..ef82b170 100644
--- a/math_functions_test.cpp
+++ b/math_functions_test.cpp
@@ -609,9 +609,15 @@ void test_u_abs()
{
std::uint16_t u = u_abs(j);
if(0 <= j)
- {LMI_TEST_EQUAL(u, j);}
+ {
+ LMI_TEST_EQUAL(u, j);
+ }
if(j <= 0)
- {LMI_TEST_EQUAL(u, -j);}
+ {
+ LMI_TEST_EQUAL(u, -j);
+ LMI_TEST_EQUAL(0, u + j);
+ LMI_TEST_EQUAL(0, j + u);
+ }
}
}
- [lmi-commits] [lmi] master updated (876d4b5b -> 50009ece), Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master e986f0c9 02/10: Specify types more explicitly in unit test, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master a6f2830d 01/10: Explain the necessity of a certain cast, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master 3c9845b4 06/10: State the purpose of a particular unit test, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master 8f5b6960 04/10: Demonstrate object sizes in unit test, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master 1744d568 07/10: Regularize every mention of nextafter(), Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master e711587c 08/10: Expunge a workaround for an obsolete compiler, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master 168e9a70 03/10: Specify a constant more clearly, Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master 7258e4ae 05/10: Establish and test explicit postconditions,
Greg Chicares <=
- [lmi-commits] [lmi] master 50009ece 10/10: x⋅(1+ε) ≢ nextafter(x) [264], Greg Chicares, 2022/06/20
- [lmi-commits] [lmi] master e7278f90 09/10: Add some functions to complement std::nextafter(), Greg Chicares, 2022/06/20