|
27 | 27 | #include <libsolutil/CommonData.h>
|
28 | 28 | #include <libsolutil/Numeric.h>
|
29 | 29 |
|
| 30 | +#include <fmt/format.h> |
| 31 | + |
30 | 32 | #include <algorithm>
|
31 | 33 | #include <limits>
|
32 | 34 | #include <locale>
|
@@ -101,110 +103,17 @@ std::string joinHumanReadablePrefixed
|
101 | 103 | return _separator + joinHumanReadable(_list, _separator, _lastSeparator);
|
102 | 104 | }
|
103 | 105 |
|
104 |
| -/// Same as @ref formatNumberReadable but only for unsigned numbers |
105 |
| -template <class T> |
106 |
| -inline std::string formatUnsignedNumberReadable ( |
107 |
| - T const& _value, |
108 |
| - bool _useTruncation = false |
109 |
| -) |
110 |
| -{ |
111 |
| - static_assert( |
112 |
| - std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, |
113 |
| - "only unsigned types or bigint supported" |
114 |
| - ); //bigint does not carry sign bit on shift |
115 |
| - |
116 |
| - // smaller numbers return as decimal |
117 |
| - if (_value <= 0x1000000) |
118 |
| - return _value.str(); |
119 |
| - |
120 |
| - HexCase hexcase = HexCase::Mixed; |
121 |
| - HexPrefix prefix = HexPrefix::Add; |
122 |
| - |
123 |
| - // when multiple trailing zero bytes, format as N * 2**x |
124 |
| - int i = 0; |
125 |
| - T v = _value; |
126 |
| - for (; (v & 0xff) == 0; v >>= 8) |
127 |
| - ++i; |
128 |
| - if (i > 2) |
129 |
| - { |
130 |
| - // 0x100 yields 2**8 (N is 1 and redundant) |
131 |
| - if (v == 1) |
132 |
| - return "2**" + std::to_string(i * 8); |
133 |
| - return toHex(toCompactBigEndian(v), prefix, hexcase) + |
134 |
| - " * 2**" + |
135 |
| - std::to_string(i * 8); |
136 |
| - } |
137 |
| - |
138 |
| - // when multiple trailing FF bytes, format as N * 2**x - 1 |
139 |
| - i = 0; |
140 |
| - for (v = _value; (v & 0xff) == 0xff; v >>= 8) |
141 |
| - ++i; |
142 |
| - if (i > 2) |
143 |
| - { |
144 |
| - // 0xFF yields 2**8 - 1 (v is 0 in that case) |
145 |
| - if (v == 0) |
146 |
| - return "2**" + std::to_string(i * 8) + " - 1"; |
147 |
| - return toHex(toCompactBigEndian(T(v + 1)), prefix, hexcase) + |
148 |
| - " * 2**" + std::to_string(i * 8) + |
149 |
| - " - 1"; |
150 |
| - } |
151 |
| - |
152 |
| - std::string str = toHex(toCompactBigEndian(_value), prefix, hexcase); |
153 |
| - if (_useTruncation) |
154 |
| - { |
155 |
| - // return as interior-truncated hex. |
156 |
| - size_t len = str.size(); |
157 |
| - |
158 |
| - if (len < 24) |
159 |
| - return str; |
160 |
| - |
161 |
| - size_t const initialChars = (prefix == HexPrefix::Add) ? 6 : 4; |
162 |
| - size_t const finalChars = 4; |
163 |
| - size_t numSkipped = len - initialChars - finalChars; |
164 |
| - |
165 |
| - return str.substr(0, initialChars) + |
166 |
| - "...{+" + |
167 |
| - std::to_string(numSkipped) + |
168 |
| - " more}..." + |
169 |
| - str.substr(len-finalChars, len); |
170 |
| - } |
171 |
| - |
172 |
| - // otherwise, show whole value. |
173 |
| - return str; |
174 |
| -} |
175 |
| - |
176 | 106 | /// Formats large numbers to be easily readable by humans.
|
177 | 107 | /// Returns decimal representation for smaller numbers; hex for large numbers.
|
178 | 108 | /// "Special" numbers, powers-of-two and powers-of-two minus 1, are returned in
|
179 | 109 | /// formulaic form like 0x01 * 2**24 - 1.
|
180 |
| -/// @a T can be any integer variable, will typically be u160, u256 or bigint. |
| 110 | +/// @a T can be any integer type, will typically be u160, u256 or bigint. |
181 | 111 | /// @param _value to be formatted
|
182 | 112 | /// @param _useTruncation if true, internal truncation is also applied,
|
183 | 113 | /// like 0x5555...{+56 more}...5555
|
184 |
| -/// @example formatNumberReadable((u256)0x7ffffff) = "0x08 * 2**24" |
185 |
| -/// @example formatNumberReadable(-57896044618658097711785492504343953926634992332820282019728792003956564819968) = -0x80 * 2**248 |
186 |
| -template <class T> |
187 |
| -inline std::string formatNumberReadable( |
188 |
| - T const& _value, |
189 |
| - bool _useTruncation = false |
190 |
| -) |
191 |
| -{ |
192 |
| - static_assert( |
193 |
| - std::numeric_limits<T>::is_integer, |
194 |
| - "only integer numbers are supported" |
195 |
| - ); |
196 |
| - |
197 |
| - if (_value >= 0) |
198 |
| - { |
199 |
| - bigint const _v = bigint(_value); |
200 |
| - return formatUnsignedNumberReadable(_v, _useTruncation); |
201 |
| - } |
202 |
| - else |
203 |
| - { |
204 |
| - bigint const _abs_value = bigint(-1) * _value; |
205 |
| - return "-" + formatUnsignedNumberReadable(_abs_value, _useTruncation); |
206 |
| - } |
207 |
| -} |
| 114 | +/// @example formatNumberReadable((u256)0x7ffffff) = "2**27 - 1" |
| 115 | +/// @example formatNumberReadable(-57896044618658097711785492504343953926634992332820282019728792003956564819968) = -2**255 |
| 116 | +std::string formatNumberReadable(bigint const& _value, bool _useTruncation = false); |
208 | 117 |
|
209 | 118 | /// Safely converts an unsigned integer as string into an unsigned int type.
|
210 | 119 | ///
|
|
0 commit comments