1#include <xrpl/protocol/STNumber.h>
3#include <xrpl/basics/Number.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/protocol/Asset.h>
8#include <xrpl/protocol/Rules.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STAmount.h>
11#include <xrpl/protocol/STBase.h>
12#include <xrpl/protocol/STTakesAsset.h>
13#include <xrpl/protocol/Serializer.h>
15#include <boost/lexical_cast.hpp>
16#include <boost/regex/v5/regbase.hpp>
17#include <boost/regex/v5/regex.hpp>
18#include <boost/regex/v5/regex_match.hpp>
39 auto mantissa = sit.
geti64();
40 auto exponent = sit.
geti32();
63 "STNumber::associateAsset",
72 XRPL_ASSERT(
getFName().isBinary(),
"xrpl::STNumber::add : field is binary");
73 XRPL_ASSERT(
getFName().fieldType ==
getSType(),
"xrpl::STNumber::add : field type match");
76 auto const mantissa =
value.mantissa();
77 auto const exponent =
value.exponent();
88 XRPL_ASSERT_PARTS(
value_ ==
value,
"xrpl::STNumber::add",
"value is already rounded");
100 "xrpl::STNumber::add",
101 "STNumber only used with large mantissa scale");
108 "xrpl::STNumber::add",
109 "mantissa in valid range");
135 return emplace(n, buf, std::move(*
this));
142 t.
getSType() == this->getSType(),
"xrpl::STNumber::isEquivalent : field type match");
143 auto const& v =
dynamic_cast<STNumber const&
>(t);
162 static boost::regex
const kReNumber(
167 "([eE]([+-]?)([0-9]+))?"
169 boost::regex_constants::optimize);
173 if (!boost::regex_match(number, match, kReNumber))
186 bool const negative = (match[1].matched && (match[1] ==
"-"));
191 if (!match[4].matched)
193 mantissa = boost::lexical_cast<std::uint64_t>(
std::string(match[2]));
199 mantissa = boost::lexical_cast<std::uint64_t>(match[2] + match[4]);
200 exponent = -(match[4].length());
203 if (match[5].matched)
206 if (match[6].matched && (match[6] ==
"-"))
208 exponent -= boost::lexical_cast<int>(
std::string(match[7]));
212 exponent += boost::lexical_cast<int>(
std::string(match[7]));
216 return {.mantissa = mantissa, .exponent = exponent, .negative = negative};
226 if (value.asInt() >= 0)
236 else if (value.isUInt())
240 else if (value.isString())
266 auto canonicalizeParts = [](
NumberParts p,
int otherExponent) {
279 auto const numberMantissa = num.
mantissa();
280 auto const numberExponent = num.
exponent();
282 auto const canonicalParts = canonicalizeParts(parts, numberExponent);
284 auto const canonicalNum = canonicalizeParts(
287 .exponent = numberExponent,
288 .negative = numberMantissa < 0,
292 if (canonicalParts.mantissa != canonicalNum.mantissa ||
293 canonicalParts.exponent != canonicalNum.exponent ||
294 canonicalParts.negative != canonicalNum.negative)
Number is a floating point type that can represent a wide range of values.
constexpr rep mantissa() const noexcept
Returns the mantissa of the external view of the Number.
static MantissaRange::MantissaScale getMantissaScale()
Returns which mantissa scale is currently in use for normalization.
constexpr int exponent() const noexcept
Returns the exponent of the external view of the Number.
static InternalRep externalToInternal(rep mantissa)
static constexpr auto kSmdNeedsAsset
bool shouldMeta(int c) const
A type which can be exported to a well known binary format.
SField const & getFName() const
static STBase * emplace(std::size_t n, void *buf, T &&val)
virtual SerializedTypeID getSType() const
void add(Serializer &s) const override
bool isDefault() const override
void associateAsset(Asset const &a) override
void setValue(Number const &v)
std::string getText() const override
bool isEquivalent(STBase const &t) const override
STBase * move(std::size_t n, void *buf) override
SerializedTypeID getSType() const override
STBase * copy(std::size_t n, void *buf) const override
Number const & value() const
Intermediate class for any STBase-derived class to store an Asset.
virtual void associateAsset(Asset const &a)
std::optional< Asset > asset_
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
NumberParts partsFromString(std::string const &number)
std::optional< Rules > const & getCurrentTransactionRules()
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
std::string to_string(BaseUInt< Bits, Tag > const &a)
void roundToAsset(A const &asset, Number &value)
Round an arbitrary precision Number IN PLACE to the precision of a given Asset.
STNumber numberFromJson(SField const &field, json::Value const &value)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)