1 //===-- Common operations on floating point numbers -------------*- C++ -*-===//
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
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
{
20 // Return the bits of a float value.
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
,
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).
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.
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.
55 // Return true if x is infinity (positive or negative.)
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.)
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.
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.
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