diff options
author | Explorer09 <explorer09@gmail.com> | 2023-07-29 16:24:12 +0800 |
---|---|---|
committer | BenBE <BenBE@geshi.org> | 2023-08-18 12:52:28 +0200 |
commit | b416433fbe7ccf935ad4e268396aa423143c2318 (patch) | |
tree | 55a38c76f4f0091ed6b06d7369706bd2f1f6f61e /Macros.h | |
parent | c6fd64fce8502a4e557711abe9fee394763ac52c (diff) |
Replace isnan() with better comparisons (isgreater(), etc.)
The standard isnan() function is defined to never throw FP exceptions
even when the argument is a "signaling" NaN. This makes isnan() more
expensive than (x != x) expression unless the compiler flag
'-fno-signaling-nans' is given.
Introduce functions isNaN(), isNonnegative(), isPositive(),
sumPositiveValues() and compareRealNumbers(), and replace isnan() in
htop's codebase with the new functions. These functions utilize
isgreater() and isgreaterequal() comparisons, which do not throw FP
exceptions on "quiet" NaNs, which htop uses extensively.
With isnan() removed, there is no need to suppress the warning
'-Wno-c11-extensions' in FreeBSD. Remove the code from 'configure.ac'.
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
Diffstat (limited to 'Macros.h')
-rw-r--r-- | Macros.h | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -2,6 +2,8 @@ #define HEADER_Macros #include <assert.h> // IWYU pragma: keep +#include <math.h> +#include <stdbool.h> #ifndef MINIMUM #define MINIMUM(a, b) ((a) < (b) ? (a) : (b)) @@ -98,6 +100,24 @@ #define IGNORE_WCASTQUAL_END #endif +/* Cheaper function for checking NaNs. Unlike the standard isnan(), this may + throw an FP exception on a "signaling" NaN. + (ISO/IEC TS 18661-1 and the C23 standard stated that isnan() throws no + exceptions even with a "signaling" NaN) */ +static inline bool isNaN(double x) { + return !isgreaterequal(x, x); +} + +/* Checks if x is nonnegative. Returns false if x is NaN. */ +static inline bool isNonnegative(double x) { + return isgreaterequal(x, 0.0); +} + +/* Checks if x is positive. Returns false if x is NaN. */ +static inline bool isPositive(double x) { + return isgreater(x, 0.0); +} + /* This subtraction is used by Linux / NetBSD / OpenBSD for calculation of CPU usage items. */ static inline unsigned long long saturatingSub(unsigned long long a, unsigned long long b) { return a > b ? a - b : 0; |