1 //===------ Pretty print function for FPBits --------------------*- 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_FPBITS_STR_H 10 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H 11 12 #include "src/__support/CPP/string.h" 13 #include "src/__support/CPP/type_traits.h" 14 #include "src/__support/FPUtil/FPBits.h" 15 #include "src/__support/integer_to_string.h" 16 #include "src/__support/macros/attributes.h" 17 #include "src/__support/macros/config.h" 18 19 namespace LIBC_NAMESPACE_DECL { 20 21 namespace details { 22 23 // Format T as uppercase hexadecimal number with leading zeros. 24 template <typename T> 25 using ZeroPaddedHexFmt = IntegerToString< 26 T, typename radix::Hex::WithWidth<(sizeof(T) * 2)>::WithPrefix::Uppercase>; 27 28 } // namespace details 29 30 // Converts the bits to a string in the following format: 31 // "0x<NNN...N> = S: N, E: 0xNNNN, M:0xNNN...N" 32 // 1. N is a hexadecimal digit. 33 // 2. The hexadecimal number on the LHS is the raw numerical representation 34 // of the bits. 35 // 3. The exponent is always 16 bits wide irrespective of the type of the 36 // floating encoding. str(fputil::FPBits<T> x)37template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) { 38 using StorageType = typename fputil::FPBits<T>::StorageType; 39 40 if (x.is_nan()) 41 return "(NaN)"; 42 if (x.is_inf()) 43 return x.is_neg() ? "(-Infinity)" : "(+Infinity)"; 44 45 const auto sign_char = [](Sign sign) -> char { 46 return sign.is_neg() ? '1' : '0'; 47 }; 48 49 cpp::string s; 50 51 const details::ZeroPaddedHexFmt<StorageType> bits(x.uintval()); 52 s += bits.view(); 53 54 s += " = (S: "; 55 s += sign_char(x.sign()); 56 57 s += ", E: "; 58 const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent()); 59 s += exponent.view(); 60 61 if constexpr (fputil::get_fp_type<T>() == fputil::FPType::X86_Binary80) { 62 s += ", I: "; 63 s += sign_char(x.get_implicit_bit() ? Sign::NEG : Sign::POS); 64 } 65 66 s += ", M: "; 67 const details::ZeroPaddedHexFmt<StorageType> mantissa(x.get_mantissa()); 68 s += mantissa.view(); 69 70 s += ')'; 71 return s; 72 } 73 74 } // namespace LIBC_NAMESPACE_DECL 75 76 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H 77