[clang] Avoid linking libdl unless needed
[llvm-project.git] / libc / utils / FPUtil / FloatOperations.h
blobff7604bc81021805715839cf726ed6d814fb3727
1 //===-- Common operations on floating point numbers -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H
10 #define LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H
12 #include "BitPatterns.h"
13 #include "FloatProperties.h"
15 #include "utils/CPP/TypeTraits.h"
17 namespace __llvm_libc {
18 namespace fputil {
20 // Return the bits of a float value.
21 template <typename T,
22 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
23 static inline typename FloatProperties<T>::BitsType valueAsBits(T x) {
24 using BitsType = typename FloatProperties<T>::BitsType;
25 return *reinterpret_cast<BitsType *>(&x);
28 // Return the float value from bits.
29 template <typename BitsType,
30 cpp::EnableIfType<
31 cpp::IsFloatingPointType<FloatTypeT<BitsType>>::Value, int> = 0>
32 static inline FloatTypeT<BitsType> valueFromBits(BitsType bits) {
33 return *reinterpret_cast<FloatTypeT<BitsType> *>(&bits);
36 // Return the bits of abs(x).
37 template <typename T,
38 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
39 static inline typename FloatProperties<T>::BitsType absBits(T x) {
40 return valueAsBits(x) & (~FloatProperties<T>::signMask);
43 // Return the zero adjusted exponent value of x.
44 template <typename T,
45 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
46 int getExponent(T x) {
47 using Properties = FloatProperties<T>;
48 using BitsType = typename Properties::BitsType;
49 BitsType bits = absBits(x);
50 int e = (bits >> Properties::mantissaWidth); // Shift out the mantissa.
51 e -= Properties::exponentOffset; // Zero adjust.
52 return e;
55 // Return true if x is infinity (positive or negative.)
56 template <typename T,
57 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
58 static inline bool isInf(T x) {
59 using Properties = FloatProperties<T>;
60 using BitsType = typename FloatProperties<T>::BitsType;
61 BitsType bits = valueAsBits(x);
62 return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
63 ((bits & Properties::mantissaMask) == 0);
66 // Return true if x is a NAN (quiet or signalling.)
67 template <typename T,
68 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
69 static inline bool isNaN(T x) {
70 using Properties = FloatProperties<T>;
71 using BitsType = typename FloatProperties<T>::BitsType;
72 BitsType bits = valueAsBits(x);
73 return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
74 ((bits & Properties::mantissaMask) != 0);
77 // Return true if x is a quiet NAN.
78 template <typename T,
79 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
80 static inline bool isQuietNaN(T x) {
81 using Properties = FloatProperties<T>;
82 using BitsType = typename FloatProperties<T>::BitsType;
83 BitsType bits = valueAsBits(x);
84 return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
85 ((bits & Properties::quietNaNMask) != 0);
88 // Return true if x is a quiet NAN with sign bit set.
89 template <typename T,
90 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
91 static inline bool isNegativeQuietNaN(T x) {
92 using Properties = FloatProperties<T>;
93 using BitsType = typename FloatProperties<T>::BitsType;
94 BitsType bits = valueAsBits(x);
95 return ((bits & BitPatterns<T>::negInf) == BitPatterns<T>::negInf) &&
96 ((bits & Properties::quietNaNMask) != 0);
99 // Return the absolute value of x.
100 template <typename T,
101 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
102 static inline T abs(T x) {
103 return valueFromBits(absBits(x));
106 } // namespace fputil
107 } // namespace __llvm_libc
109 #endif // LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H