Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
float_properties.hpp
Go to the documentation of this file.
1// Copyright 2025, Toyota Motor Corporation
2
3#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_PROPERTIES_HPP_
4#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_PROPERTIES_HPP_
5
6// IWYU pragma: private, include "arene/base/math.hpp"
7// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
8
9#include "arene/base/compiler_support/diagnostics.hpp"
10#include "arene/base/stdlib_choice/numeric_limits.hpp"
11
12// parasoft-begin-suppress CERT_CPP-DCL51-f "False positive: these names are not reserved in namespace arene::base"
13// parasoft-begin-suppress AUTOSAR-A7_1_5-a "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
14
15namespace arene {
16namespace base {
17
18// parasoft-begin-suppress AUTOSAR-M0_1_2-d "False positive: comparison result is not always false for floating point"
19// parasoft-begin-suppress AUTOSAR-M6_2_2-a "Equality is to check the properties of one value, not compare two values"
20
21ARENE_IGNORE_START();
22ARENE_IGNORE_ALL("-Wfloat-equal", "Equality is used to check the properties of a single value, not compare two values");
23
24namespace float_properties_detail {
25
26/// @brief Check whether or not the argument has a NaN value
27/// @tparam T Type of the number to check
28/// @param num The number to check
29/// @return @c true if @c num has a NaN value, otherwise @c false
30template <typename T>
31constexpr auto isnan(T const num) noexcept -> bool {
32 // NOLINTNEXTLINE(misc-redundant-expression) This expression is not trivially false for floating point numbers
33 return num != num;
34}
35
36/// @brief Check whether or not the argument has a (positive or negative) infinite value
37/// @tparam T Type of the number to check
38/// @param num The number to check
39/// @return @c true if @c num has an infinite value, otherwise @c false
40template <typename T>
41constexpr auto isinf(T const num) noexcept -> bool {
42 return (num == std::numeric_limits<T>::infinity()) || (num == -std::numeric_limits<T>::infinity());
43}
44
45/// @brief Check whether or not the argument is finite, i.e. not infinity or NaN
46/// @tparam T Type of the number to check
47/// @param num The number to check
48/// @return @c true if @c num has a finite value, otherwise @c false
49template <typename T>
50constexpr auto isfinite(T const num) noexcept -> bool {
51 return (!::arene::base::float_properties_detail::isnan(num)) && (!::arene::base::float_properties_detail::isinf(num));
52}
53
54/// @brief Check whether or not the argument is normal, i.e. not infinity, NaN, subnormal, or zero
55/// @tparam T Type of the number to check
56/// @param num The number to check
57/// @return @c true if @c num has a normal value, otherwise @c false
58template <typename T>
59constexpr auto isnormal(T num) noexcept -> bool {
60 // This explicit check for NaN is needed for GCC, because it erroneously thinks that using a NaN makes an expression
61 // no longer eligible for constexpr.
62 if (::arene::base::float_properties_detail::isnan(num)) {
63 return false;
64 }
65
66 if (num < static_cast<T>(0.0)) {
67 // This is faster than a fully correct abs because it doesn't need to deal with corner cases like signed zero/NaN;
68 // for the purposes of determining normality it's fine.
69 num = -num;
70 }
71
72 // numeric_limits::min() for a floating-point type is the smallest *normal* value.
73 return (num >= std::numeric_limits<T>::min()) && (num < std::numeric_limits<T>::infinity());
74}
75
76ARENE_IGNORE_END();
77
78// parasoft-end-suppress AUTOSAR-M0_1_2-d
79// parasoft-end-suppress AUTOSAR-M6_2_2-a
80
81} // namespace float_properties_detail
82
83/// @brief Check whether or not the argument has a NaN value
84/// @param num The number to check
85/// @return @c true if @c num has a NaN value, otherwise @c false
86constexpr auto isnan(float const num) noexcept -> bool { return float_properties_detail::isnan(num); }
87
88/// @brief Check whether or not the argument has a NaN value
89/// @param num The number to check
90/// @return @c true if @c num has a NaN value, otherwise @c false
91constexpr auto isnan(double const num) noexcept -> bool { return float_properties_detail::isnan(num); }
92
93/// @brief Check whether or not the argument has a (positive or negative) infinite value
94/// @param num The number to check
95/// @return @c true if @c num has an infinite value, otherwise @c false
96constexpr auto isinf(float const num) noexcept -> bool { return float_properties_detail::isinf(num); }
97
98/// @brief Check whether or not the argument has a (positive or negative) infinite value
99/// @param num The number to check
100/// @return @c true if @c num has an infinite value, otherwise @c false
101constexpr auto isinf(double const num) noexcept -> bool { return float_properties_detail::isinf(num); }
102
103/// @brief Check whether or not the argument is finite, i.e. not infinity or NaN
104/// @param num The number to check
105/// @return @c true if @c num has a finite value, otherwise @c false
106constexpr auto isfinite(float const num) noexcept -> bool { return float_properties_detail::isfinite(num); }
107
108/// @brief Check whether or not the argument is finite, i.e. not infinity or NaN
109/// @param num The number to check
110/// @return @c true if @c num has a finite value, otherwise @c false
111constexpr auto isfinite(double const num) noexcept -> bool { return float_properties_detail::isfinite(num); }
112
113/// @brief Check whether or not the argument is normal, i.e. not infinity, NaN, subnormal, or zero
114/// @param num The number to check
115/// @return @c true if @c num has a normal value, otherwise @c false
116constexpr auto isnormal(float const num) noexcept -> bool { return float_properties_detail::isnormal(num); }
117
118/// @brief Check whether or not the argument is normal, i.e. not infinity, NaN, subnormal, or zero
119/// @param num The number to check
120/// @return @c true if @c num has a normal value, otherwise @c false
121constexpr auto isnormal(double const num) noexcept -> bool { return float_properties_detail::isnormal(num); }
122
123} // namespace base
124} // namespace arene
125
126// parasoft-end-suppress CERT_CPP-DCL51-f
127// parasoft-end-suppress AUTOSAR-A7_1_5-a
128
129#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_PROPERTIES_HPP_
Definition array_exceptions_disabled.cpp:11
constexpr auto isfinite(float const num) noexcept -> bool
Check whether or not the argument is finite, i.e. not infinity or NaN.
Definition float_properties.hpp:106
ARENE_IGNORE_ALL("-Wfloat-equal", "Equality is used to check the properties of a single value, not compare two values")
constexpr auto isnormal(float const num) noexcept -> bool
Check whether or not the argument is normal, i.e. not infinity, NaN, subnormal, or zero.
Definition float_properties.hpp:116
constexpr auto isinf(float const num) noexcept -> bool
Check whether or not the argument has a (positive or negative) infinite value.
Definition float_properties.hpp:96
constexpr auto isnan(double const num) noexcept -> bool
Check whether or not the argument has a NaN value.
Definition float_properties.hpp:91
constexpr auto isinf(double const num) noexcept -> bool
Check whether or not the argument has a (positive or negative) infinite value.
Definition float_properties.hpp:101
constexpr auto isnormal(double const num) noexcept -> bool
Check whether or not the argument is normal, i.e. not infinity, NaN, subnormal, or zero.
Definition float_properties.hpp:121
constexpr auto isnan(float const num) noexcept -> bool
Check whether or not the argument has a NaN value.
Definition float_properties.hpp:86
constexpr auto isfinite(double const num) noexcept -> bool
Check whether or not the argument is finite, i.e. not infinity or NaN.
Definition float_properties.hpp:111
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10