xrpld
Loading...
Searching...
No Matches
xrpl::Number Class Referencefinal

Number is a floating point type that can represent a wide range of values. More...

#include <Number.h>

Collaboration diagram for xrpl::Number:

Classes

struct  Unchecked
struct  Normalized
class  Guard

Public Types

enum class  RoundingMode { ToNearest , TowardsZero , Downward , Upward }

Public Member Functions

constexpr Number ()=default
 Number (rep mantissa)
 Number (rep mantissa, int exponent)
constexpr Number (bool negative, internalrep mantissa, int exponent, Unchecked) noexcept
constexpr Number (internalrep mantissa, int exponent, Unchecked) noexcept
 Number (bool negative, internalrep mantissa, int exponent, Normalized)
 Number (internalrep mantissa, int exponent, Normalized)
constexpr rep mantissa () const noexcept
 Returns the mantissa of the external view of the Number.
constexpr int exponent () const noexcept
 Returns the exponent of the external view of the Number.
constexpr Number operator+ () const noexcept
constexpr Number operator- () const noexcept
Numberoperator++ ()
Number operator++ (int)
Numberoperator-- ()
Number operator-- (int)
Numberoperator+= (Number const &x)
Numberoperator-= (Number const &x)
Numberoperator*= (Number const &x)
Numberoperator/= (Number const &x)
 operator rep () const
 Conversions to Number are implicit and conversions away from Number are explicit.
constexpr int signum () const noexcept
 Return the sign of the amount.
Number truncate () const noexcept
template<auto MinMantissa, auto MaxMantissa, Integral64 T = std::decay_t<decltype(MinMantissa)>>
std::pair< T, int > normalizeToRange () const

Static Public Member Functions

static Number min () noexcept
static Number max () noexcept
static Number lowest () noexcept
static RoundingMode getround ()
static RoundingMode setround (RoundingMode inMode)
static MantissaRange::MantissaScale getMantissaScale ()
 Returns which mantissa scale is currently in use for normalization.
static void setMantissaScale (MantissaRange::MantissaScale scale)
 Changes which mantissa scale is used for normalization.
static internalrep minMantissa ()
static internalrep maxMantissa ()
static int mantissaLog ()
static Number one ()

Static Public Attributes

static constexpr int kMinExponent = -32768
static constexpr int kMaxExponent = 32768
static constexpr internalrep kMaxRep = std::numeric_limits<rep>::max()

Private Types

using rep = std::int64_t
using internalrep = MantissaRange::rep

Private Member Functions

void normalize (MantissaRange const &range)
bool isnormal () const noexcept
Number shiftExponent (int exponentDelta) const

Static Private Member Functions

template<class T>
static void normalize (bool &negative, T &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFixEnabled)
 Normalize Number components to an arbitrary range.
static internalrep externalToInternal (rep mantissa)
template<>
void normalize (bool &negative, uint128_t &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFixEnabled)
template<>
void normalize (bool &negative, unsigned long long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFixEnabled)
template<>
void normalize (bool &negative, unsigned long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFixEnabled)

Private Attributes

bool negative_ {false}
internalrep mantissa_ {0}
int exponent_ {std::numeric_limits<int>::lowest()}

Static Private Attributes

static RoundingMode mode = Number::RoundingMode::ToNearest
static std::reference_wrapper< MantissaRange const > kRange

Friends

constexpr bool operator== (Number const &x, Number const &y) noexcept
constexpr bool operator!= (Number const &x, Number const &y) noexcept
constexpr bool operator< (Number const &l, Number const &r) noexcept
constexpr bool operator> (Number const &x, Number const &y) noexcept
constexpr bool operator<= (Number const &x, Number const &y) noexcept
constexpr bool operator>= (Number const &x, Number const &y) noexcept
std::ostreamoperator<< (std::ostream &os, Number const &x)
std::string to_string (Number const &amount)
Number root (Number f, unsigned d)
Number root2 (Number f)
template<class T>
void doNormalize (bool &negative, T &mantissa, int &exponent, MantissaRange::rep const &minMantissa, MantissaRange::rep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFixEnabled, bool dropped)

Detailed Description

Number is a floating point type that can represent a wide range of values.

It can represent all values that can be represented by an STAmount - regardless of asset type - XRPAmount, MPTAmount, and IOUAmount, with at least as much precision as those types require.

-— Internal Representation -—

Internally, Number is represented with three values:

  1. a bool sign flag,
  2. a std::uint64_t mantissa,
  3. an int exponent.

The internal mantissa is an unsigned integer in the range defined by the current MantissaRange. The exponent is an integer in the range [minExponent, maxExponent].

See the description of MantissaRange for more details on the ranges.

A non-zero mantissa is (almost) always normalized, meaning it and the exponent are grown or shrunk until the mantissa is in the range [MantissaRange.min, MantissaRange.max].

Note:

  1. Normalization can be disabled by using the "unchecked" ctor tag. This should only be used at specific conversion points, some constexpr values, and in unit tests.
  2. The max of the "large" range, 10^19-1, is the largest 10^X-1 value that fits in an unsigned 64-bit number. (10^19-1 < 2^64-1 and 10^20-1 > 2^64-1). This avoids under- and overflows.

-— External Interface -—

The external interface of Number consists of a std::int64_t mantissa, which is restricted to 63-bits, and an int exponent, which must be in the range [minExponent, maxExponent]. The range of the mantissa depends on which MantissaRange is currently active. For the "short" range, the mantissa will be between 10^15 and 10^16-1. For the "large" range, the mantissa will be between -(2^63-1) and 2^63-1. As noted above, the "large" range is needed to represent the full range of valid XRP and MPT integer values accurately.

Note:

  1. 2^63-1 is between 10^18 and 10^19-1, which are the limits of the "large" mantissa range.
  2. The functions mantissa() and exponent() return the external view of the Number value, specifically using a signed 63-bit mantissa. This may require altering the internal representation to fit into that range before the value is returned. The interface guarantees consistency of the two values.
  3. Number cannot represent -2^63 (std::numeric_limits<std::int64_t>::min()) as an exact integer, but it doesn't need to, because all asset values on-ledger are non-negative. This is due to implementation details of several operations which use unsigned arithmetic internally. This is sufficient to represent all valid XRP values (where the absolute value can not exceed INITIAL_XRP: 10^17), and MPT values (where the absolute value can not exceed maxMPTokenAmount: 2^63-1).

-— Mantissa Range Switching -—

The mantissa range may be changed at runtime via setMantissaScale(). The default mantissa range is "large". The range is updated whenever transaction processing begins, based on whether SingleAssetVault or LendingProtocol are enabled. If either is enabled, the mantissa range is set to "large". If not, it is set to "small", preserving backward compatibility and correct "amendment-gating".

It is extremely unlikely that any more calls to setMantissaScale() will be needed outside of unit tests.

-— Usage With Different Ranges -—

Outside of unit tests, and existing checks, code that uses Number should not know or care which mantissa range is active.

The results of computations using Numbers with a small mantissa may differ from computations using Numbers with a large mantissa, specifically as it effects the results after rounding. That is why the large mantissa range is amendment gated in transaction processing.

It is extremely unlikely that any more calls to getMantissaScale() will be needed outside of unit tests.

Code that uses Number should not assume or check anything about the mantissa() or exponent() except that they fit into the "large" range specified in the "External Interface" section.

--— Unit Tests --—

Within unit tests, it may be useful to explicitly switch between the two ranges, or to check which range is active when checking the results of computations. If the test is doing the math directly, the set/getMantissaScale() functions may be most appropriate. However, if the test has anything to do with transaction processing, it should enable or disable the amendments that control the mantissa range choice (SingleAssetVault and LendingProtocol), and/or check if either of those amendments are enabled to determine which result to expect.

Definition at line 305 of file Number.h.

Member Typedef Documentation

◆ rep

Definition at line 307 of file Number.h.

◆ internalrep

Definition at line 308 of file Number.h.

Member Enumeration Documentation

◆ RoundingMode

enum class xrpl::Number::RoundingMode
strong
Enumerator
ToNearest 
TowardsZero 
Downward 
Upward 

Definition at line 493 of file Number.h.

Constructor & Destructor Documentation

◆ Number() [1/7]

xrpl::Number::Number ( )
explicitconstexprdefault

◆ Number() [2/7]

xrpl::Number::Number ( rep mantissa)

Definition at line 630 of file Number.h.

◆ Number() [3/7]

xrpl::Number::Number ( rep mantissa,
int exponent )
explicit

Definition at line 625 of file Number.h.

◆ Number() [4/7]

xrpl::Number::Number ( bool negative,
internalrep mantissa,
int exponent,
Unchecked  )
explicitconstexprnoexcept

Definition at line 602 of file Number.h.

◆ Number() [5/7]

xrpl::Number::Number ( internalrep mantissa,
int exponent,
Unchecked  )
explicitconstexprnoexcept

Definition at line 607 of file Number.h.

◆ Number() [6/7]

xrpl::Number::Number ( bool negative,
internalrep mantissa,
int exponent,
Normalized  )
explicit

Definition at line 614 of file Number.h.

◆ Number() [7/7]

xrpl::Number::Number ( internalrep mantissa,
int exponent,
Normalized  )
explicit

Definition at line 620 of file Number.h.

Member Function Documentation

◆ mantissa()

Number::rep xrpl::Number::mantissa ( ) const
nodiscardconstexprnoexcept

Returns the mantissa of the external view of the Number.

Please see the "---- External Interface ----" section of the class documentation for an explanation of why the internal value may be modified.

Definition at line 640 of file Number.h.

◆ exponent()

int xrpl::Number::exponent ( ) const
nodiscardconstexprnoexcept

Returns the exponent of the external view of the Number.

Please see the "---- External Interface ----" section of the class documentation for an explanation of why the internal value may be modified.

Definition at line 661 of file Number.h.

◆ operator+()

Number xrpl::Number::operator+ ( ) const
constexprnoexcept

Definition at line 676 of file Number.h.

◆ operator-()

Number xrpl::Number::operator- ( ) const
constexprnoexcept

Definition at line 682 of file Number.h.

◆ operator++() [1/2]

Number & xrpl::Number::operator++ ( )

Definition at line 692 of file Number.h.

◆ operator++() [2/2]

Number xrpl::Number::operator++ ( int )

Definition at line 699 of file Number.h.

◆ operator--() [1/2]

Number & xrpl::Number::operator-- ( )

Definition at line 707 of file Number.h.

◆ operator--() [2/2]

Number xrpl::Number::operator-- ( int )

Definition at line 714 of file Number.h.

◆ operator+=()

Number & xrpl::Number::operator+= ( Number const & x)

Definition at line 691 of file Number.cpp.

◆ operator-=()

Number & xrpl::Number::operator-= ( Number const & x)

Definition at line 722 of file Number.h.

◆ operator*=()

Number & xrpl::Number::operator*= ( Number const & x)

Definition at line 792 of file Number.cpp.

◆ operator/=()

Number & xrpl::Number::operator/= ( Number const & x)

Definition at line 854 of file Number.cpp.

◆ min()

Number xrpl::Number::min ( )
staticnoexcept

Definition at line 760 of file Number.h.

◆ max()

Number xrpl::Number::max ( )
staticnoexcept

Definition at line 766 of file Number.h.

◆ lowest()

Number xrpl::Number::lowest ( )
staticnoexcept

Definition at line 772 of file Number.h.

◆ operator rep()

xrpl::Number::operator rep ( ) const
explicit

Conversions to Number are implicit and conversions away from Number are explicit.

This design encourages and facilitates the use of Number as the preferred type for floating point arithmetic as it makes "mixed mode" more convenient, e.g. MPTAmount + Number.

Definition at line 1033 of file Number.cpp.

◆ signum()

int xrpl::Number::signum ( ) const
nodiscardconstexprnoexcept

Return the sign of the amount.

Definition at line 449 of file Number.h.

◆ truncate()

Number xrpl::Number::truncate ( ) const
nodiscardnoexcept

Definition at line 1062 of file Number.cpp.

◆ getround()

Number::RoundingMode xrpl::Number::getround ( )
static

Definition at line 105 of file Number.cpp.

◆ setround()

Number::RoundingMode xrpl::Number::setround ( RoundingMode inMode)
static

Definition at line 111 of file Number.cpp.

◆ getMantissaScale()

MantissaRange::MantissaScale xrpl::Number::getMantissaScale ( )
static

Returns which mantissa scale is currently in use for normalization.

If you think you need to call this outside of unit tests, no you don't.

Definition at line 117 of file Number.cpp.

◆ setMantissaScale()

void xrpl::Number::setMantissaScale ( MantissaRange::MantissaScale scale)
static

Changes which mantissa scale is used for normalization.

If you think you need to call this outside of unit tests, no you don't.

Definition at line 123 of file Number.cpp.

◆ minMantissa()

internalrep xrpl::Number::minMantissa ( )
static

Definition at line 516 of file Number.h.

◆ maxMantissa()

internalrep xrpl::Number::maxMantissa ( )
static

Definition at line 522 of file Number.h.

◆ mantissaLog()

int xrpl::Number::mantissaLog ( )
static

Definition at line 528 of file Number.h.

◆ one()

Number xrpl::Number::one ( )
static

Definition at line 519 of file Number.cpp.

◆ normalizeToRange()

template<auto MinMantissa, auto MaxMantissa, Integral64 T>
std::pair< T, int > xrpl::Number::normalizeToRange ( ) const
nodiscard

Definition at line 789 of file Number.h.

◆ normalize() [1/5]

void xrpl::Number::normalize ( MantissaRange const & range)
private

Definition at line 666 of file Number.cpp.

◆ normalize() [2/5]

template<class T>
void xrpl::Number::normalize ( bool & negative,
T & mantissa,
int & exponent,
internalrep const & minMantissa,
internalrep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled )
staticprivate

Normalize Number components to an arbitrary range.

min/maxMantissa are parameters because this function is used by both normalize(), which reads from kRange, and by normalizeToRange, which is public and can accept an arbitrary range from the caller.

◆ isnormal()

bool xrpl::Number::isnormal ( ) const
nodiscardprivatenoexcept

Definition at line 778 of file Number.h.

◆ shiftExponent()

Number xrpl::Number::shiftExponent ( int exponentDelta) const
nodiscardprivate

Definition at line 675 of file Number.cpp.

◆ externalToInternal()

Number::internalrep xrpl::Number::externalToInternal ( rep mantissa)
staticprivate

Definition at line 500 of file Number.cpp.

◆ normalize() [3/5]

template<>
void xrpl::Number::normalize ( bool & negative,
uint128_t & mantissa,
int & exponent,
internalrep const & minMantissa,
internalrep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled )
staticprivate

Definition at line 616 of file Number.cpp.

◆ normalize() [4/5]

template<>
void xrpl::Number::normalize ( bool & negative,
unsigned long long & mantissa,
int & exponent,
internalrep const & minMantissa,
internalrep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled )
staticprivate

Definition at line 634 of file Number.cpp.

◆ normalize() [5/5]

template<>
void xrpl::Number::normalize ( bool & negative,
unsigned long & mantissa,
int & exponent,
internalrep const & minMantissa,
internalrep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled )
staticprivate

Definition at line 652 of file Number.cpp.

◆ operator==

bool operator== ( Number const & x,
Number const & y )
friend

Definition at line 398 of file Number.h.

◆ operator!=

bool operator!= ( Number const & x,
Number const & y )
friend

Definition at line 405 of file Number.h.

◆ operator<

bool operator< ( Number const & l,
Number const & r )
friend

Definition at line 410 of file Number.h.

◆ operator>

bool operator> ( Number const & x,
Number const & y )
friend

Definition at line 460 of file Number.h.

◆ operator<=

bool operator<= ( Number const & x,
Number const & y )
friend

Definition at line 465 of file Number.h.

◆ operator>=

bool operator>= ( Number const & x,
Number const & y )
friend

Definition at line 472 of file Number.h.

◆ operator<<

std::ostream & operator<< ( std::ostream & os,
Number const & x )
friend

Definition at line 477 of file Number.h.

◆ to_string

std::string to_string ( Number const & amount)
friend

Definition at line 1080 of file Number.cpp.

◆ root

Number root ( Number f,
unsigned d )
friend

Definition at line 1201 of file Number.cpp.

◆ root2

Number root2 ( Number f)
friend

Definition at line 1275 of file Number.cpp.

◆ doNormalize

template<class T>
void doNormalize ( bool & negative,
T & mantissa,
int & exponent,
MantissaRange::rep const & minMantissa,
MantissaRange::rep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled,
bool dropped )
friend

Definition at line 527 of file Number.cpp.

Member Data Documentation

◆ negative_

bool xrpl::Number::negative_ {false}
private

Definition at line 310 of file Number.h.

◆ mantissa_

internalrep xrpl::Number::mantissa_ {0}
private

Definition at line 311 of file Number.h.

◆ exponent_

int xrpl::Number::exponent_ {std::numeric_limits<int>::lowest()}
private

Definition at line 312 of file Number.h.

◆ kMinExponent

int xrpl::Number::kMinExponent = -32768
staticconstexpr

Definition at line 316 of file Number.h.

◆ kMaxExponent

int xrpl::Number::kMaxExponent = 32768
staticconstexpr

Definition at line 317 of file Number.h.

◆ kMaxRep

internalrep xrpl::Number::kMaxRep = std::numeric_limits<rep>::max()
staticconstexpr

Definition at line 319 of file Number.h.

◆ mode

Number::RoundingMode xrpl::Number::mode = Number::RoundingMode::ToNearest
thread_localstaticprivate

Definition at line 545 of file Number.h.

◆ kRange

std::reference_wrapper< MantissaRange const > xrpl::Number::kRange
thread_localstaticprivate
Initial value:

Definition at line 551 of file Number.h.