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;
60 std::tie(result.mantissa_, result.exponent_) =
85 Throw<std::overflow_error>(
"value overflow");
105 Throw<std::overflow_error>(
"IOUAmount::normalize");
118 Throw<std::overflow_error>(
"value overflow");
127 Throw<std::overflow_error>(
"value overflow");
135 if (other == beast::zero)
138 if (*
this == beast::zero)
187 using namespace boost::multiprecision;
190 Throw<std::runtime_error>(
"division by zero");
195 static auto const powerTable = [] {
199 for (
int i = 0; i < 30; ++i)
209 static auto log10Floor = [](uint128_t
const& v) {
221 static auto log10Ceil = [](uint128_t
const& v) {
230 bool const neg = amt.
mantissa() < 0;
231 uint128_t
const den128(den);
234 uint128_t
const mul = uint128_t(neg ? -amt.
mantissa() : amt.
mantissa()) * uint128_t(num);
236 auto low = mul / den128;
237 uint128_t rem(mul - low * den128);
249 auto const roomToGrow = fl64 - log10Ceil(low);
252 exponent -= roomToGrow;
253 low *= powerTable[roomToGrow];
254 rem *= powerTable[roomToGrow];
256 auto const addRem = rem / den128;
258 rem = rem - addRem * den128;
265 bool hasRem = bool(rem);
266 auto const mustShrink = log10Ceil(low) - fl64;
269 uint128_t
const sav(low);
270 exponent += mustShrink;
271 low /= powerTable[mustShrink];
273 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()