1 //===-- Basic 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 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_BASIC_OPERATIONS_H 10 #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_BASIC_OPERATIONS_H 11 12 #include "FPBits.h" 13 14 #include "src/__support/CPP/TypeTraits.h" 15 16 namespace __llvm_libc { 17 namespace fputil { 18 19 template <typename T, 20 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> 21 static inline T abs(T x) { 22 FPBits<T> bits(x); 23 bits.set_sign(0); 24 return T(bits); 25 } 26 27 template <typename T, 28 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> 29 static inline T fmin(T x, T y) { 30 FPBits<T> bitx(x), bity(y); 31 32 if (bitx.is_nan()) { 33 return y; 34 } else if (bity.is_nan()) { 35 return x; 36 } else if (bitx.get_sign() != bity.get_sign()) { 37 // To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and 38 // y has different signs and both are not NaNs, we return the number 39 // with negative sign. 40 return (bitx.get_sign() ? x : y); 41 } else { 42 return (x < y ? x : y); 43 } 44 } 45 46 template <typename T, 47 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> 48 static inline T fmax(T x, T y) { 49 FPBits<T> bitx(x), bity(y); 50 51 if (bitx.is_nan()) { 52 return y; 53 } else if (bity.is_nan()) { 54 return x; 55 } else if (bitx.get_sign() != bity.get_sign()) { 56 // To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and 57 // y has different signs and both are not NaNs, we return the number 58 // with positive sign. 59 return (bitx.get_sign() ? y : x); 60 } else { 61 return (x > y ? x : y); 62 } 63 } 64 65 template <typename T, 66 cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0> 67 static inline T fdim(T x, T y) { 68 FPBits<T> bitx(x), bity(y); 69 70 if (bitx.is_nan()) { 71 return x; 72 } 73 74 if (bity.is_nan()) { 75 return y; 76 } 77 78 return (x > y ? x - y : 0); 79 } 80 81 } // namespace fputil 82 } // namespace __llvm_libc 83 84 #endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_BASIC_OPERATIONS_H 85