From b5c5029e93831639f77dc81c55784536415074cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Bartoletti?= Date: Thu, 14 Dec 2023 19:55:36 +0100 Subject: [PATCH] qgis.h: proposes a generic templated method from qgsDoubleNear and qgsNumberNear --- python/PyQt6/core/auto_generated/qgis.sip.in | 1 + python/core/auto_generated/qgis.sip.in | 1 + src/core/qgis.h | 38 ++++++++++++-------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/python/PyQt6/core/auto_generated/qgis.sip.in b/python/PyQt6/core/auto_generated/qgis.sip.in index 93eb673d1c8..c479998c030 100644 --- a/python/PyQt6/core/auto_generated/qgis.sip.in +++ b/python/PyQt6/core/auto_generated/qgis.sip.in @@ -2555,6 +2555,7 @@ Compare two doubles, treating nan values as equal .. versionadded:: 3.20 %End + bool qgsDoubleNear( double a, double b, double epsilon = 4 * DBL_EPSILON ); %Docstring Compare two doubles (but allow some difference) diff --git a/python/core/auto_generated/qgis.sip.in b/python/core/auto_generated/qgis.sip.in index 0a208cdb697..e28de3c0320 100644 --- a/python/core/auto_generated/qgis.sip.in +++ b/python/core/auto_generated/qgis.sip.in @@ -2555,6 +2555,7 @@ Compare two doubles, treating nan values as equal .. versionadded:: 3.20 %End + bool qgsDoubleNear( double a, double b, double epsilon = 4 * DBL_EPSILON ); %Docstring Compare two doubles (but allow some difference) diff --git a/src/core/qgis.h b/src/core/qgis.h index 5508941ba54..5eb8c04bbb1 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -4419,6 +4419,28 @@ inline bool qgsNanCompatibleEquals( double a, double b ) return a == b; } +#ifndef SIP_RUN + +/** + * Compare two numbers of type T (but allow some difference) + * \param a first number + * \param b second number + * \param epsilon maximum difference allowable between numbers + * \since 3.36 + */ +template +inline bool qgsNumberNear( T a, T b, T epsilon = std::numeric_limits::epsilon() * 4 ) +{ + const bool aIsNan = std::isnan( a ); + const bool bIsNan = std::isnan( b ); + if ( aIsNan || bIsNan ) + return aIsNan && bIsNan; + + const T diff = a - b; + return diff >= -epsilon && diff <= epsilon; +} +#endif + /** * Compare two doubles (but allow some difference) * \param a first double @@ -4427,13 +4449,7 @@ inline bool qgsNanCompatibleEquals( double a, double b ) */ inline bool qgsDoubleNear( double a, double b, double epsilon = 4 * std::numeric_limits::epsilon() ) { - const bool aIsNan = std::isnan( a ); - const bool bIsNan = std::isnan( b ); - if ( aIsNan || bIsNan ) - return aIsNan && bIsNan; - - const double diff = a - b; - return diff >= -epsilon && diff <= epsilon; + return qgsNumberNear( a, b, epsilon ); } /** @@ -4444,13 +4460,7 @@ inline bool qgsDoubleNear( double a, double b, double epsilon = 4 * std::numeric */ inline bool qgsFloatNear( float a, float b, float epsilon = 4 * FLT_EPSILON ) { - const bool aIsNan = std::isnan( a ); - const bool bIsNan = std::isnan( b ); - if ( aIsNan || bIsNan ) - return aIsNan && bIsNan; - - const float diff = a - b; - return diff >= -epsilon && diff <= epsilon; + return qgsNumberNear( a, b, epsilon ); } //! Compare two doubles using specified number of significant digits