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>
38 auto mantissa = sit.
geti64();
39 auto exponent = sit.
geti32();
62 "STNumber::associateAsset",
71 XRPL_ASSERT(
getFName().isBinary(),
"xrpl::STNumber::add : field is binary");
72 XRPL_ASSERT(
getFName().fieldType ==
getSType(),
"xrpl::STNumber::add : field type match");
75 auto const mantissa =
value.mantissa();
76 auto const exponent =
value.exponent();
87 XRPL_ASSERT_PARTS(
value_ ==
value,
"xrpl::STNumber::add",
"value is already rounded");
99 "xrpl::STNumber::add",
100 "STNumber only used with large mantissa scale");
107 "xrpl::STNumber::add",
108 "mantissa in valid range");
134 return emplace(n, buf, std::move(*
this));
141 t.
getSType() == this->getSType(),
"xrpl::STNumber::isEquivalent : field type match");
142 auto const& v =
dynamic_cast<STNumber const&
>(t);
161 static boost::regex
const kReNumber(
166 "([eE]([+-]?)([0-9]+))?"
168 boost::regex_constants::optimize);
172 if (!boost::regex_match(number, match, kReNumber))
185 bool const negative = (match[1].matched && (match[1] ==
"-"));
190 if (!match[4].matched)
192 mantissa = boost::lexical_cast<std::uint64_t>(
std::string(match[2]));
198 mantissa = boost::lexical_cast<std::uint64_t>(match[2] + match[4]);
199 exponent = -(match[4].length());
202 if (match[5].matched)
205 if (match[6].matched && (match[6] ==
"-"))
207 exponent -= boost::lexical_cast<int>(
std::string(match[7]));
211 exponent += boost::lexical_cast<int>(
std::string(match[7]));
215 return {.mantissa = mantissa, .exponent = exponent, .negative = negative};
225 if (value.asInt() >= 0)
235 else if (value.isUInt())
239 else if (value.isString())
265 auto canonicalizeParts = [](
NumberParts p,
int otherExponent) {
278 auto const numberMantissa = num.
mantissa();
279 auto const numberExponent = num.
exponent();
281 auto const canonicalParts = canonicalizeParts(parts, numberExponent);
283 auto const canonicalNum = canonicalizeParts(
286 .exponent = numberExponent,
287 .negative = numberMantissa < 0,
291 if (canonicalParts.mantissa != canonicalNum.mantissa ||
292 canonicalParts.exponent != canonicalNum.exponent ||
293 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.
static internalrep externalToInternal(rep mantissa)
constexpr int exponent() const noexcept
Returns the exponent of the external view of the Number.
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)