This commit is contained in:
2025-04-09 10:22:44 +02:00
commit 96ff5392c8
330 changed files with 28300 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.28)
# define CXX interface library
# define target & alias (for other projects consuming the "source-tree")
add_library(iue-num_num INTERFACE)
# define sources of target
target_sources(iue-num_num
INTERFACE FILE_SET public_headers TYPE HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR} FILES numerics.hpp)
# define installation step
install(TARGETS iue-num_num EXPORT iue-num-export
FILE_SET public_headers DESTINATION "./")
# define test
if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL)
add_executable(iue-num_num.test numerics.test.cpp)
target_link_libraries(iue-num_num.test iue-num_num)
add_test(NAME iue-num_num.test COMMAND iue-num_num.test)
endif()
# export targets for consuming cmake projects
# generate and install a .cmake file to allow dependend projects consuming the "install-tree" to import all targets
install(EXPORT iue-num-export DESTINATION "iue-num" )
# allow dependend projects consuming the "build-tree" to use all targets
export(EXPORT iue-num-export)
+26
View File
@@ -0,0 +1,26 @@
/// @file
/// @brief Supporting functionality for numeric calculations with floating point values
#pragma once
#include <cmath> // std::abs, std::max, std::min
namespace iue::num {
/// @brief Checks if two floating point values are close to each other
/// @param a First value
/// @param b Second value
/// @param tabs Tolerance for the absolute difference:
/// abs(a - b) < tabs
/// @param trel Tolerance for the relative error (using the larger absolute value as reference):
/// abs(a b) < trel * max(abs(a),abs(b))
/// @return true if the stronger of the two tolerances is met, false otherwise
inline bool isclose(double a, double b, double tabs = 0.0, double trel = 1e-9) {
if (a == b) // for infinite values (which should be considered close to themselves)
return true;
auto abs_diff = std::abs(a - b); // absolte difference
auto trel_ref = std::max(std::abs(a), std::abs(b)); // reference for the relative threshold
return abs_diff < std::max(tabs, trel * trel_ref);
}
} // namespace iue::num
+69
View File
@@ -0,0 +1,69 @@
/// @file
/// @brief Test for iue::num::islcose
#include "iue-num/numerics.hpp" // iue::num::islcose
#include <cassert> // assert
#include <cstdlib> // EXIT_SUCCESS
#include <limits> // std::numeric_limits
int main() {
const double eps = std::numeric_limits<double>::epsilon();
const double inf = std::numeric_limits<double>::infinity();
const double nan = std::numeric_limits<double>::quiet_NaN();
{ // infinity
assert(iue::num::isclose(inf, inf, 0.0, 0.0));
assert(iue::num::isclose(-inf, -inf, 0.0, 0.0));
assert(!iue::num::isclose(-inf, inf, 0.0, 0.0));
assert(!iue::num::isclose(inf, -inf, 0.0, 0.0));
}
{ // nan
assert(!iue::num::isclose(nan, nan, inf, inf));
}
{ // around 1.0
double a = 1.0;
double b = 1.0 + eps;
// rel error
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
assert(!iue::num::isclose(a, b, 0.0, 0.0));
// abs error
assert(iue::num::isclose(a, b, 2 * eps, 0.0));
assert(!iue::num::isclose(a, b, 0.0, 0.0));
}
{ // around 1e10
double a = 1.0 * 1e10;
double b = (1.0 + eps) * 1e10;
// rel error
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
assert(!iue::num::isclose(a, b, 0.0, 0.0));
// abs error
assert(iue::num::isclose(a, b, 1e10 * 2 * eps, 0.0));
assert(!iue::num::isclose(a, b, 1e9 * 2 * eps, 0.0));
}
{ // around 1e-10
double a = 1.0 * 1e-10;
double b = (1.0 + eps) * 1e-10;
// rel error
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
assert(!iue::num::isclose(a, b, 0.0, 0.0));
// abs error
assert(iue::num::isclose(a, b, 1e-10 * 2 * eps, 0.0));
assert(!iue::num::isclose(a, b, 1e-11 * 2 * eps, 0.0));
}
return EXIT_SUCCESS;
}