1 //===-- Floating point classification functions -----------------*- 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 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
10 #define LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
11
12 #include "BitPatterns.h"
13 #include "FloatOperations.h"
14 #include "FloatProperties.h"
15
16 #include "utils/CPP/TypeTraits.h"
17
18 namespace __llvm_libc {
19 namespace fputil {
20
bitsAreInf(BitsType bits)21 template <typename BitsType> static inline bool bitsAreInf(BitsType bits) {
22 using FPType = typename FloatType<BitsType>::Type;
23 return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
24 ((bits & FloatProperties<FPType>::mantissaMask) == 0);
25 }
26
27 // Return true if x is infinity (positive or negative.)
28 template <typename T,
29 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isInf(T x)30 static inline bool isInf(T x) {
31 return bitsAreInf(valueAsBits(x));
32 }
33
bitsAreNaN(BitsType bits)34 template <typename BitsType> static inline bool bitsAreNaN(BitsType bits) {
35 using FPType = typename FloatType<BitsType>::Type;
36 return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
37 ((bits & FloatProperties<FPType>::mantissaMask) != 0);
38 }
39
40 // Return true if x is a NAN (quiet or signalling.)
41 template <typename T,
42 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isNaN(T x)43 static inline bool isNaN(T x) {
44 return bitsAreNaN(valueAsBits(x));
45 }
46
bitsAreInfOrNaN(BitsType bits)47 template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
48 using FPType = typename FloatType<BitsType>::Type;
49 return (bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf;
50 }
51
bitsAreZero(BitsType bits)52 template <typename BitsType> static inline bool bitsAreZero(BitsType bits) {
53 using FPType = typename FloatType<BitsType>::Type;
54 return (bits == BitPatterns<FPType>::zero) ||
55 (bits == BitPatterns<FPType>::negZero);
56 }
57
58 // Return true if x is any kind of NaN or infinity.
59 template <typename T,
60 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isInfOrNaN(T x)61 static inline bool isInfOrNaN(T x) {
62 return bitsAreInfOrNaN(valueAsBits(x));
63 }
64
65 // Return true if x is a quiet NAN.
66 template <typename T,
67 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isQuietNaN(T x)68 static inline bool isQuietNaN(T x) {
69 using Properties = FloatProperties<T>;
70 using BitsType = typename FloatProperties<T>::BitsType;
71 BitsType bits = valueAsBits(x);
72 return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
73 ((bits & Properties::quietNaNMask) != 0);
74 }
75
76 // Return true if x is a quiet NAN with sign bit set.
77 template <typename T,
78 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isNegativeQuietNaN(T x)79 static inline bool isNegativeQuietNaN(T x) {
80 using Properties = FloatProperties<T>;
81 using BitsType = typename FloatProperties<T>::BitsType;
82 BitsType bits = valueAsBits(x);
83 return ((bits & BitPatterns<T>::negInf) == BitPatterns<T>::negInf) &&
84 ((bits & Properties::quietNaNMask) != 0);
85 }
86
87 } // namespace fputil
88 } // namespace __llvm_libc
89
90 #endif // LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
91