20 #include <ripple/basics/IOUAmount.h>
21 #include <ripple/basics/contract.h>
22 #include <boost/multiprecision/cpp_int.hpp>
66 Throw<std::overflow_error>(
"IOUAmount::normalize");
79 Throw<std::overflow_error>(
"value overflow");
88 if (other == beast::zero)
91 if (*
this == beast::zero)
161 if (amount == beast::zero)
164 int const exponent = amount.
exponent();
168 if (((exponent != 0) && ((exponent < -25) || (exponent > -5))))
176 bool negative =
false;
180 mantissa = -mantissa;
184 assert(exponent + 43 > 0);
186 size_t const pad_prefix = 27;
187 size_t const pad_suffix = 23;
193 val.
append(pad_prefix,
'0');
195 val.
append(pad_suffix,
'0');
197 size_t const offset(exponent + 43);
199 auto pre_from(val.
begin());
200 auto const pre_to(val.
begin() + offset);
202 auto const post_from(val.
begin() + offset);
203 auto post_to(val.
end());
208 pre_from += pad_prefix;
210 assert(post_to >= post_from);
212 pre_from =
std::find_if(pre_from, pre_to, [](
char c) {
return c !=
'0'; });
217 post_to -= pad_suffix;
219 assert(post_to >= post_from);
224 [](
char c) {
return c !=
'0'; })
233 if (pre_from == pre_to)
236 ret.
append(pre_from, pre_to);
238 if (post_to != post_from)
241 ret.
append(post_from, post_to);
254 using namespace boost::multiprecision;
257 Throw<std::runtime_error>(
"division by zero");
262 static auto const powerTable = [] {
266 for (
int i = 0; i < 30; ++i)
276 static auto log10Floor = [](uint128_t
const& v) {
289 static auto log10Ceil = [](uint128_t
const& v) {
297 static auto const fl64 =
300 bool const neg = amt.
mantissa() < 0;
301 uint128_t
const den128(den);
304 uint128_t
const mul =
307 auto low = mul / den128;
308 uint128_t rem(mul - low * den128);
320 auto const roomToGrow = fl64 - log10Ceil(low);
323 exponent -= roomToGrow;
324 low *= powerTable[roomToGrow];
325 rem *= powerTable[roomToGrow];
327 auto const addRem = rem / den128;
329 rem = rem - addRem * den128;
336 bool hasRem = bool(rem);
337 auto const mustShrink = log10Ceil(low) - fl64;
340 uint128_t
const sav(low);
341 exponent += mustShrink;
342 low /= powerTable[mustShrink];
344 hasRem = bool(sav - low * powerTable[mustShrink]);