20 #include <ripple/basics/IOUAmount.h>
21 #include <ripple/basics/contract.h>
22 #include <boost/multiprecision/cpp_int.hpp>
60 Throw<std::overflow_error>(
"value overflow");
80 Throw<std::overflow_error>(
"IOUAmount::normalize");
93 Throw<std::overflow_error>(
"value overflow");
100 : mantissa_(other.mantissa()), exponent_(other.exponent())
103 Throw<std::overflow_error>(
"value overflow");
111 if (other == beast::zero)
114 if (*
this == beast::zero)
167 using namespace boost::multiprecision;
170 Throw<std::runtime_error>(
"division by zero");
175 static auto const powerTable = [] {
179 for (
int i = 0; i < 30; ++i)
189 static auto log10Floor = [](uint128_t
const& v) {
202 static auto log10Ceil = [](uint128_t
const& v) {
210 static auto const fl64 =
213 bool const neg = amt.
mantissa() < 0;
214 uint128_t
const den128(den);
217 uint128_t
const mul =
220 auto low = mul / den128;
221 uint128_t rem(mul - low * den128);
233 auto const roomToGrow = fl64 - log10Ceil(low);
236 exponent -= roomToGrow;
237 low *= powerTable[roomToGrow];
238 rem *= powerTable[roomToGrow];
240 auto const addRem = rem / den128;
242 rem = rem - addRem * den128;
249 bool hasRem = bool(rem);
250 auto const mustShrink = log10Ceil(low) - fl64;
253 uint128_t
const sav(low);
254 exponent += mustShrink;
255 low /= powerTable[mustShrink];
257 hasRem = bool(sav - low * powerTable[mustShrink]);