Forked from
Eclipse Projects / Eclipse openpass / mantle-api
171 commits behind, 1 commit ahead of the upstream repository.
-
Martin Stump authored
* Move "doc", "include" and "test" to the root dir * Rename to MantleAPI Signed-off-by:
Martin Stump <martin.stump@mercedes-benz.com>
Martin Stump authored* Move "doc", "include" and "test" to the root dir * Rename to MantleAPI Signed-off-by:
Martin Stump <martin.stump@mercedes-benz.com>
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
floating_point_helper.h 4.52 KiB
/*******************************************************************************
* Copyright (c) 2021, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
//-----------------------------------------------------------------------------
/** @file floating_point_helper.h */
//-----------------------------------------------------------------------------
#ifndef MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H
#define MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H
#include <units.h>
#include <cmath>
#include <limits>
#include <type_traits>
namespace mantle_api
{
/// @brief Compares two floating point numbers for equality.
///
/// **Attention** No approximation of the correct precision for the actual value is done!
///
/// This function uses a default precision of `std::numeric_limts<T>::epsilon()`, which means that without providing the
/// precision yourself, it is only suited for
/// * bit-wise equal numbers
/// * numbers around 1 or smaller
///
/// @tparam T Floating point type, ensured by SFINAE
/// @param lhs Left-hand operand
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if both numbers are equal within the given precision.
inline bool IsEqual(double lhs, double rhs, double precision = std::numeric_limits<double>::epsilon())
{
return std::abs(lhs - rhs) < precision;
}
/// @brief Compares two floating point numbers for equality.
///
/// **Attention** No approximation of the correct precision for the actual value is done!
///
/// This function uses a default precision of `std::numeric_limts<T>::epsilon()`, which means that without providing the
/// precision yourself, it is only suited for
/// * bit-wise equal numbers
/// * numbers around 1 or smaller
///
/// @tparam T Floating point type, ensured by SFINAE
/// @param lhs Left-hand operand
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if both numbers are equal within the given precision.
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool IsEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
return units::unit_cast<double>(units::math::abs(lhs - rhs)) < precision;
}
/// @brief Compares two floating point numbers for equality.
///
/// **Attention** No approximation of the correct precision for the actual value is done!
///
/// This function uses a default precision of `std::numeric_limts<T>::epsilon()`, which means that without providing the
/// precision yourself, it is only suited for
/// * bit-wise equal numbers
/// * numbers around 1 or smaller
///
/// @tparam T Floating point type, ensured by SFINAE
/// @param lhs Left-hand operand
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if lhs is greater than rhs or both numbers are equal within the given precision.
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool GreaterOrEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
if (lhs > rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
}
/// @brief Compares two floating point numbers for equality.
///
/// **Attention** No approximation of the correct precision for the actual value is done!
///
/// This function uses a default precision of `std::numeric_limts<T>::epsilon()`, which means that without providing the
/// precision yourself, it is only suited for
/// * bit-wise equal numbers
/// * numbers around 1 or smaller
///
/// @tparam T Floating point type, ensured by SFINAE
/// @param lhs Left-hand operand
/// @param rhs Right-hand operand
/// @param precision Given precision, defaults to `std::numeric_limits<T>::epsilon()`.
/// @return True if lhs is less than rhs or both numbers are equal within the given precision.
template <typename T, class = typename std::enable_if_t<units::traits::is_unit_t<T>::value>>
bool LessOrEqual(T lhs, T rhs, double precision = std::numeric_limits<double>::epsilon())
{
if (lhs < rhs)
{
return true;
}
return IsEqual(lhs, rhs, precision);
}
} // namespace mantle_api
#endif // MANTLEAPI_COMMON_FLOATING_POINT_HELPER_H