20 #include <ripple/basics/contract.h>
21 #include <ripple/basics/IOUAmount.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);
215 post_to -= pad_suffix;
217 assert (post_to >= post_from);
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 = []
267 for (
int i = 0; i < 30; ++i)
277 static auto log10Floor = [](uint128_t
const& v)
281 auto const l =
std::lower_bound (powerTable.begin (), powerTable.end (), v);
290 static auto log10Ceil = [](uint128_t
const& v)
294 auto const l =
std::lower_bound (powerTable.begin (), powerTable.end (), v);
298 static auto const fl64 =
301 bool const neg = amt.
mantissa () < 0;
302 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]);