1 #pragma once
2 // manipulators.hpp: definitions of helper functions for areal type manipulation
3 //
4 // Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
5 //
6 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
7 #include <iostream>
8 #include <iomanip>
9 #include <typeinfo> // for typeid()
10
11 // pull in the color printing for shells utility
12 #include <universal/utility/color_print.hpp>
13
14 // This file contains functions that manipulate a posit type
15 // using posit number system knowledge.
16
17 namespace sw::universal {
18
19 // Generate a type tag for this posit, for example, posit<8,1>
20 template<size_t nbits, size_t es, typename bt>
type_tag(const areal<nbits,es,bt> & v)21 std::string type_tag(const areal<nbits, es, bt>& v) {
22 std::stringstream ss;
23 ss << "areal<" << nbits << "," << es << ">";
24 return ss.str();
25 }
26
27 // Generate a string representing the areal components: sign, exponent, faction, uncertainty bit, and value
28 template<size_t nbits, size_t es, typename bt>
components(const areal<nbits,es,bt> & v)29 std::string components(const areal<nbits, es, bt>& v) {
30 std::stringstream ss;
31 bool s{ false };
32 int e{ 0 };
33 blockbinary<v.fbits> f;
34 bool u{ false };
35 decode(v, s, e, f, u);
36
37 // TODO: hardcoded field width is governed by pretty printing areal tables, which by construction will always be small areals
38 ss << std::setw(14) << to_binary(v)
39 << " Sign : " << std::setw(2) << s
40 << " Exponent : " << std::setw(5) << e
41 << " Fraction : " << std::setw(8) << std::setprecision(21) << "TBD"
42 << " Uncertainty : " << std::setw(2) << u
43 << " Value : " << std::setw(16) << u;
44
45 return ss.str();
46 }
47
48 // generate a binary string for areal
49 template<size_t nbits, size_t es, typename bt>
to_hex(const areal<nbits,es,bt> & v)50 inline std::string to_hex(const areal<nbits, es, bt>& v) {
51 constexpr size_t bitsInByte = 8;
52 constexpr size_t bitsInBlock = sizeof(bt) * bitsInByte;
53 char hexChar[16] = {
54 '0', '1', '2', '3', '4', '5', '6', '7',
55 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
56 };
57 std::stringstream ss;
58 ss << "0x" << std::hex;
59 long nrNibbles = long(1ull + ((nbits - 1ull) >> 2ull));
60 for (long n = nrNibbles - 1; n >= 0; --n) {
61 uint8_t nibble = v.nibble(size_t(n));
62 ss << hexChar[nibble];
63 if (n > 0 && ((n * 4ll) % bitsInBlock) == 0) ss << '\'';
64 }
65 return ss.str();
66 }
67
68 // generate a areal format ASCII format nbits.esxNN...NNa
69 template<size_t nbits, size_t es, typename bt>
hex_print(const areal<nbits,es,bt> & r)70 inline std::string hex_print(const areal<nbits, es, bt>& r) {
71 std::stringstream ss;
72 ss << nbits << '.' << es << 'x' << to_hex(r) << 'r';
73 return ss.str();
74 }
75
76 template<size_t nbits, size_t es, typename bt>
pretty_print(const areal<nbits,es,bt> & r,int printPrecision=std::numeric_limits<double>::max_digits10)77 std::string pretty_print(const areal<nbits, es, bt>& r, int printPrecision = std::numeric_limits<double>::max_digits10) {
78 std::stringstream ss;
79 constexpr size_t fbits = areal<nbits, es, bt>::fbits;
80 bool s{ false };
81 blockbinary<es, bt> e;
82 blockbinary<fbits, bt> f;
83 bool ubit{ false };
84 decode(r, s, e, f, ubit);
85
86 // sign bit
87 ss << (r.isneg() ? '1' : '0');
88
89 // exponent bits
90 ss << '-';
91 for (int i = int(es) - 1; i >= 0; --i) {
92 ss << (e.test(i) ? '1' : '0');
93 }
94
95 // fraction bits
96 ss << '-';
97 for (int i = int(r.fbits) - 1; i >= 0; --i) {
98 ss << (f.test(i) ? '1' : '0');
99 }
100
101 // uncertainty bit
102 ss << '-';
103 ss << (r.test(0) ? "1" : "0");
104 return ss.str();
105 }
106
107 template<size_t nbits, size_t es, typename bt>
info_print(const areal<nbits,es,bt> & p,int printPrecision=17)108 std::string info_print(const areal<nbits, es, bt>& p, int printPrecision = 17) {
109 return "TBD";
110 }
111
112 template<size_t nbits, size_t es, typename bt>
color_print(const areal<nbits,es,bt> & r)113 std::string color_print(const areal<nbits, es, bt>& r) {
114 std::stringstream ss;
115 bool s{ false };
116 blockbinary<es,bt> e;
117 blockbinary<areal<nbits, es, bt>::fbits> f;
118 bool ubit{ false };
119 decode(r, s, e, f, ubit);
120
121 Color red(ColorCode::FG_RED);
122 Color yellow(ColorCode::FG_YELLOW);
123 Color blue(ColorCode::FG_BLUE);
124 Color magenta(ColorCode::FG_MAGENTA);
125 Color cyan(ColorCode::FG_CYAN);
126 Color white(ColorCode::FG_WHITE);
127 Color def(ColorCode::FG_DEFAULT);
128
129 // sign bit
130 ss << red << (r.isneg() ? "1" : "0");
131
132 // exponent bits
133 for (int i = int(es) - 1; i >= 0; --i) {
134 ss << cyan << (e.test(i) ? '1' : '0');
135 }
136
137 // fraction bits
138 for (int i = int(r.fbits) - 1; i >= 0; --i) {
139 ss << magenta << (f.test(i) ? '1' : '0');
140 }
141
142 // uncertainty bit
143 ss << yellow << (r.test(0) ? "1" : "0");
144
145 ss << def;
146 return ss.str();
147 }
148
149 } // namespace sw::universal
150
151