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