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