xref: /aosp_15_r20/external/llvm-libc/src/__support/FPUtil/fpbits_str.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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)37 template <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