20 #include <ripple/basics/IOUAmount.h>
21 #include <ripple/basics/contract.h>
22 #include <boost/multiprecision/cpp_int.hpp>
60 Throw<std::overflow_error>(
"IOUAmount::normalize");
73 Throw<std::overflow_error>(
"value overflow");
82 if (other == beast::zero)
85 if (*
this == beast::zero)
155 if (amount == beast::zero)
158 int const exponent = amount.
exponent();
162 if (((exponent != 0) && ((exponent < -25) || (exponent > -5))))
170 bool negative =
false;
174 mantissa = -mantissa;
178 assert(exponent + 43 > 0);
180 size_t const pad_prefix = 27;
181 size_t const pad_suffix = 23;
187 val.
append(pad_prefix,
'0');
189 val.
append(pad_suffix,
'0');
191 size_t const offset(exponent + 43);
193 auto pre_from(val.
begin());
194 auto const pre_to(val.
begin() + offset);
196 auto const post_from(val.
begin() + offset);
197 auto post_to(val.
end());
202 pre_from += pad_prefix;
204 assert(post_to >= post_from);
206 pre_from =
std::find_if(pre_from, pre_to, [](
char c) {
return c !=
'0'; });
211 post_to -= pad_suffix;
213 assert(post_to >= post_from);
218 [](
char c) {
return c !=
'0'; })
227 if (pre_from == pre_to)
230 ret.
append(pre_from, pre_to);
232 if (post_to != post_from)
235 ret.
append(post_from, post_to);
248 using namespace boost::multiprecision;
251 Throw<std::runtime_error>(
"division by zero");
256 static auto const powerTable = [] {
260 for (
int i = 0; i < 30; ++i)
270 static auto log10Floor = [](uint128_t
const& v) {
283 static auto log10Ceil = [](uint128_t
const& v) {
291 static auto const fl64 =
294 bool const neg = amt.
mantissa() < 0;
295 uint128_t
const den128(den);
298 uint128_t
const mul =
301 auto low = mul / den128;
302 uint128_t rem(mul - low * den128);
314 auto const roomToGrow = fl64 - log10Ceil(low);
317 exponent -= roomToGrow;
318 low *= powerTable[roomToGrow];
319 rem *= powerTable[roomToGrow];
321 auto const addRem = rem / den128;
323 rem = rem - addRem * den128;
330 bool hasRem = bool(rem);
331 auto const mustShrink = log10Ceil(low) - fl64;
334 uint128_t
const sav(low);
335 exponent += mustShrink;
336 low /= powerTable[mustShrink];
338 hasRem = bool(sav - low * powerTable[mustShrink]);