[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master aaf4595 2/4: Ascertain identity element for s
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master aaf4595 2/4: Ascertain identity element for std::max() and std::min() |
Date: |
Sun, 7 Mar 2021 15:05:41 -0500 (EST) |
branch: master
commit aaf4595a4da3faa7cda97a82497c1066170ad47d
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Ascertain identity element for std::max() and std::min()
"supremum" means LUB, and "infimum" means GLB. Chose these terms not
because of their precise mathematical definitions but because the terms
"max" and especially "min" have been spoiled by the Standard: DBL_MAX
is not maximal because it's less than positive infinity; and DBL_MIN
is greater than most doubles because it is not even negative, and it is
not even the lowest positive double, as denorm_min() < min().
---
miscellany.hpp | 22 ++++++++++++++++++++++
miscellany_test.cpp | 14 ++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/miscellany.hpp b/miscellany.hpp
index 56c5e64..f101e5a 100644
--- a/miscellany.hpp
+++ b/miscellany.hpp
@@ -83,6 +83,28 @@ std::string floating_rep(T t)
return oss.str();
}
+template<typename T>
+constexpr T infimum()
+{
+ using limits = std::numeric_limits<T>;
+ static_assert(limits::is_bounded);
+ if constexpr(limits::has_infinity)
+ return -limits::infinity();
+ else
+ return limits::min();
+}
+
+template<typename T>
+constexpr T supremum()
+{
+ using limits = std::numeric_limits<T>;
+ static_assert(limits::is_bounded);
+ if constexpr(limits::has_infinity)
+ return limits::infinity();
+ else
+ return limits::max();
+}
+
/// Ascertain vector minimum and maximum efficiently.
///
/// Heterogeneous relational operators are necessarily free functions.
diff --git a/miscellany_test.cpp b/miscellany_test.cpp
index f3390a0..6c68916 100644
--- a/miscellany_test.cpp
+++ b/miscellany_test.cpp
@@ -26,6 +26,7 @@
#include "test_tools.hpp"
#include <cfloat> // DBL_MAX
+#include <cmath> // HUGE_VAL
#include <cstdio> // remove()
#include <fstream>
#include <limits>
@@ -131,6 +132,18 @@ void test_files_are_identical()
std::remove(f1);
}
+void test_sup_inf()
+{
+ LMI_TEST_EQUAL( false , infimum <bool >());
+ LMI_TEST_EQUAL( true , supremum<bool >());
+ LMI_TEST_EQUAL( INT_MIN , infimum <int >());
+ LMI_TEST_EQUAL( INT_MAX , supremum<int >());
+ LMI_TEST_EQUAL(-HUGE_VAL, infimum <double>());
+ LMI_TEST_EQUAL( HUGE_VAL, supremum<double>());
+
+ LMI_TEST_EQUAL( 0 , infimum <unsigned int>());
+}
+
void test_minmax()
{
double const zero = 0.0;
@@ -412,6 +425,7 @@ int test_main(int, char*[])
{
test_each_equal();
test_files_are_identical();
+ test_sup_inf();
test_minmax();
test_prefix_and_suffix();
test_scale_power();