1#include <xrpl/protocol/IOUAmount.h>
4#include <xrpl/basics/LocalValue.h>
5#include <xrpl/basics/Number.h>
6#include <xrpl/basics/contract.h>
7#include <xrpl/beast/utility/Zero.h>
8#include <xrpl/protocol/STAmount.h>
10#include <boost/multiprecision/cpp_int.hpp>
26getStaticSTNumberSwitchover()
28 static LocalValue<bool> r{
true};
36 return *getStaticSTNumberSwitchover();
42 *getStaticSTNumberSwitchover() = v;
84 Throw<std::overflow_error>(
"value overflow");
104 Throw<std::overflow_error>(
"IOUAmount::normalize");
117 Throw<std::overflow_error>(
"value overflow");
126 Throw<std::overflow_error>(
"value overflow");
134 if (other == beast::zero)
137 if (*
this == beast::zero)
186 using namespace boost::multiprecision;
189 Throw<std::runtime_error>(
"division by zero");
194 static auto const powerTable = [] {
198 for (
int i = 0; i < 30; ++i)
208 static auto log10Floor = [](uint128_t
const& v) {
220 static auto log10Ceil = [](uint128_t
const& v) {
229 bool const neg = amt.
mantissa() < 0;
230 uint128_t
const den128(den);
233 uint128_t
const mul = uint128_t(neg ? -amt.
mantissa() : amt.
mantissa()) * uint128_t(num);
235 auto low = mul / den128;
236 uint128_t rem(mul - low * den128);
248 auto const roomToGrow = fl64 - log10Ceil(low);
251 exponent -= roomToGrow;
252 low *= powerTable[roomToGrow];
253 rem *= powerTable[roomToGrow];
255 auto const addRem = rem / den128;
257 rem = rem - addRem * den128;
264 bool hasRem = bool(rem);
265 auto const mustShrink = log10Ceil(low) - fl64;
268 uint128_t
const sav(low);
269 exponent += mustShrink;
270 low /= powerTable[mustShrink];
272 hasRem = bool(sav - low * powerTable[mustShrink]);
Floating point representation of amounts with high dynamic range.
IOUAmount & operator+=(IOUAmount const &other)
mantissa_type mantissa() const noexcept
exponent_type exponent() const noexcept
static IOUAmount fromNumber(Number const &number)
static IOUAmount minPositiveAmount()
void normalize()
Adjusts the mantissa and exponent to the proper range.
Number is a floating point type that can represent a wide range of values.
std::pair< T, int > normalizeToRange(T minMantissa, T maxMantissa) const
static constexpr std::uint64_t cMaxValue
static int const cMaxOffset
static constexpr std::uint64_t cMinValue
static int const cMinOffset
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
static std::int64_t constexpr minMantissa
std::string to_string(base_uint< Bits, Tag > const &a)
void setSTNumberSwitchover(bool v)
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
static std::int64_t constexpr maxMantissa
static int constexpr maxExponent
static int constexpr minExponent
bool getSTNumberSwitchover()