Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
float_sign.hpp
Go to the documentation of this file.
1// parasoft-suppress AUTOSAR-A2_8_1-a "False positive: builtin_signbit_is_constexpr does relate to floating point signs"
2// Copyright 2025, Toyota Motor Corporation
3
4#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_SIGN_HPP_
5#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_SIGN_HPP_
6
7// IWYU pragma: private, include "arene/base/math.hpp"
8// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
9
10#include "arene/base/compiler_support/diagnostics.hpp"
11#include "arene/base/constraints/constraints.hpp"
12#include "arene/base/stdlib_choice/enable_if.hpp"
13#include "arene/base/stdlib_choice/integral_constant.hpp"
14
15// parasoft-begin-suppress CERT_CPP-DCL51-f "False positive: these names are not reserved in namespace arene::base"
16// parasoft-begin-suppress AUTOSAR-M17_0_3-a "False positive: the names are added in namespace arene::base"
17// parasoft-begin-suppress AUTOSAR-A7_1_5-a "Trailing return syntax permitted by A7-1-5 Permit #1 v1.0.0"
18
19namespace arene {
20namespace base {
21
22/// @brief Return a number with the magnitude of the first operand and the sign of the second
23/// @param magnitude The operand to take the magnitude from
24/// @param sign The operand to take the sign from
25/// @return A value with the same absolute value as @c magnitude and the same sign as @c sign
26constexpr auto copysign(float const magnitude, float const sign) noexcept -> float {
27 return __builtin_copysignf(magnitude, sign);
28}
29
30/// @brief Return a number with the magnitude of the first operand and the sign of the second
31/// @param magnitude The operand to take the magnitude from
32/// @param sign The operand to take the sign from
33/// @return A value with the same absolute value as @c magnitude and the same sign as @c sign
34constexpr auto copysign(double const magnitude, double const sign) noexcept -> double {
35 return __builtin_copysign(magnitude, sign);
36}
37
38namespace float_sign_detail {
39/// @brief Type trait to check whether or not __builtin_signbit is constexpr for the given argument type
40/// @tparam T Argument type with which __builtin_signbit will be called
41template <typename T, typename = constraints<>>
42class builtin_signbit_is_constexpr : public std::false_type {};
43
44/// @brief Type trait to check whether or not __builtin_signbit is constexpr for the given argument type
45/// @tparam T Argument type with which __builtin_signbit will be called
46template <typename T>
47class builtin_signbit_is_constexpr<T, constraints<std::enable_if_t<(static_cast<void>(__builtin_signbit(T{})), true)>>>
48 : public std::true_type {};
49
50/// @brief Type trait to check whether or not __builtin_signbit is constexpr for the given argument type
51/// @tparam T Argument type with which __builtin_signbit will be called
52template <typename T>
53constexpr bool builtin_signbit_is_constexpr_v = builtin_signbit_is_constexpr<T>::value;
54
55/// @brief Implementation of @c signbit function when @c __builtin_signbit is constexpr (all GCC versions, Clang v20.1+)
56/// @tparam T Argument type to check the sign bit of
57/// @param num Value to check the sign bit of
58/// @return @c true if @c num is *negative* (i.e. its sign bit is 1), @c false if @c num is positive
59template <typename T, constraints<std::enable_if_t<builtin_signbit_is_constexpr_v<T>>> = nullptr>
60constexpr auto signbit(T const num) noexcept -> bool {
61 return __builtin_signbit(num);
62}
63
64ARENE_IGNORE_START();
65ARENE_IGNORE_ALL("-Wfloat-equal", "Equality operand is guaranteed to be either exactly 1.0 or exactly -1.0");
66
67/// @brief Implementation of @c signbit function when @c __builtin_signbit is *not* constexpr (Clang v19.4-)
68/// @tparam T Argument type to check the sign bit of
69/// @param num Value to check the sign bit of
70/// @return @c true if @c num is *negative* (i.e. its sign bit is 1), @c false if @c num is positive
71template <typename T, constraints<std::enable_if_t<!builtin_signbit_is_constexpr_v<T>>> = nullptr>
72constexpr auto signbit(T const num) noexcept -> bool {
73 // ISO/IEC 60559 does not guarantee that this will work when num is a NaN, but it does work in practice on the
74 // relevant platforms. Its correctness is checked in the unit tests.
75 auto sign_carrier = ::arene::base::copysign(static_cast<T>(1.0), num);
76 return sign_carrier == static_cast<T>(-1.0);
77}
78
79ARENE_IGNORE_END();
80
81} // namespace float_sign_detail
82
83/// @brief Check the sign bit of a floating point number
84/// @param num The number to check
85/// @return @c true if @c num is *negative* (i.e. its sign bit is 1), @c false if @c num is positive
86constexpr auto signbit(float const num) noexcept -> bool { return float_sign_detail::signbit(num); }
87
88/// @brief Check the sign bit of a floating point number
89/// @param num The number to check
90/// @return @c true if @c num is *negative* (i.e. its sign bit is 1), @c false if @c num is positive
91constexpr auto signbit(double const num) noexcept -> bool { return float_sign_detail::signbit(num); }
92
93} // namespace base
94} // namespace arene
95
96// parasoft-end-suppress CERT_CPP-DCL51-f
97// parasoft-end-suppress AUTOSAR-M17_0_3-a
98// parasoft-end-suppress AUTOSAR-A7_1_5-a
99
100#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MATH_FLOAT_SIGN_HPP_
Definition array_exceptions_disabled.cpp:11
constexpr auto signbit(double const num) noexcept -> bool
Check the sign bit of a floating point number.
Definition float_sign.hpp:91
constexpr auto copysign(double const magnitude, double const sign) noexcept -> double
Return a number with the magnitude of the first operand and the sign of the second.
Definition float_sign.hpp:34
constexpr auto copysign(float const magnitude, float const sign) noexcept -> float
Return a number with the magnitude of the first operand and the sign of the second.
Definition float_sign.hpp:26
constexpr auto signbit(float const num) noexcept -> bool
Check the sign bit of a floating point number.
Definition float_sign.hpp:86
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10