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
 Guard. More...

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 internalrep externalToInternal (rep mantissa)

Static Public Attributes

static constexpr int kMinExponent = -32768
static constexpr int kMaxExponent = 32768
static constexpr internalrep kMaxRep = std::numeric_limits<rep>::max()
static constexpr internalrep kMaxRepUp = ((kMaxRep / 10) + 1) * 10

Private Types

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

Private Member Functions

void normalize (MantissaRange const &range)
void normalize (Guard const &guard)
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 cuspRoundingFix)
 Normalize Number components to an arbitrary range.
template<>
void normalize (bool &negative, uint128_t &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFix)
template<>
void normalize (bool &negative, unsigned long long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFix)
template<>
void normalize (bool &negative, unsigned long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFix)

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 &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 cuspRoundingFix, 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 kInitialXRP: 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 350 of file Number.h.

Member Typedef Documentation

◆ rep

Definition at line 352 of file Number.h.

◆ internalrep

Definition at line 353 of file Number.h.

Member Enumeration Documentation

◆ RoundingMode

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

Definition at line 537 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 681 of file Number.h.

◆ Number() [3/7]

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

Definition at line 676 of file Number.h.

◆ Number() [4/7]

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

Definition at line 653 of file Number.h.

◆ Number() [5/7]

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

Definition at line 658 of file Number.h.

◆ Number() [6/7]

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

Definition at line 665 of file Number.h.

◆ Number() [7/7]

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

Definition at line 671 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 692 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 714 of file Number.h.

◆ operator+()

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

Definition at line 729 of file Number.h.

◆ operator-()

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

Definition at line 735 of file Number.h.

◆ operator++() [1/2]

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

Definition at line 745 of file Number.h.

◆ operator++() [2/2]

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

Definition at line 752 of file Number.h.

◆ operator--() [1/2]

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

Definition at line 760 of file Number.h.

◆ operator--() [2/2]

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

Definition at line 767 of file Number.h.

◆ operator+=()

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

Definition at line 879 of file libxrpl/basics/Number.cpp.

◆ operator-=()

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

Definition at line 775 of file Number.h.

◆ operator*=()

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

Definition at line 1087 of file libxrpl/basics/Number.cpp.

◆ operator/=()

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

Definition at line 1141 of file libxrpl/basics/Number.cpp.

◆ min()

Number xrpl::Number::min ( )
staticnoexcept

Definition at line 813 of file Number.h.

◆ max()

Number xrpl::Number::max ( )
staticnoexcept

Definition at line 819 of file Number.h.

◆ lowest()

Number xrpl::Number::lowest ( )
staticnoexcept

Definition at line 825 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 1320 of file libxrpl/basics/Number.cpp.

◆ signum()

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

Return the sign of the amount.

Definition at line 493 of file Number.h.

◆ truncate()

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

Definition at line 1349 of file libxrpl/basics/Number.cpp.

◆ getround()

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

Definition at line 133 of file libxrpl/basics/Number.cpp.

◆ setround()

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

Definition at line 139 of file libxrpl/basics/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 145 of file libxrpl/basics/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 151 of file libxrpl/basics/Number.cpp.

◆ minMantissa()

internalrep xrpl::Number::minMantissa ( )
static

Definition at line 562 of file Number.h.

◆ maxMantissa()

internalrep xrpl::Number::maxMantissa ( )
static

Definition at line 568 of file Number.h.

◆ mantissaLog()

int xrpl::Number::mantissaLog ( )
static

Definition at line 574 of file Number.h.

◆ one()

Number xrpl::Number::one ( )
static

Definition at line 703 of file libxrpl/basics/Number.cpp.

◆ normalizeToRange()

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

Definition at line 842 of file Number.h.

◆ externalToInternal()

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

Definition at line 684 of file libxrpl/basics/Number.cpp.

◆ normalize() [1/6]

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

Definition at line 842 of file libxrpl/basics/Number.cpp.

◆ normalize() [2/6]

void xrpl::Number::normalize ( Guard const & guard)
private

Definition at line 848 of file libxrpl/basics/Number.cpp.

◆ normalize() [3/6]

template<class T>
void xrpl::Number::normalize ( bool & negative,
T & mantissa,
int & exponent,
internalrep const & minMantissa,
internalrep const & maxMantissa,
MantissaRange::CuspRoundingFix cuspRoundingFix )
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 831 of file Number.h.

◆ shiftExponent()

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

Definition at line 863 of file libxrpl/basics/Number.cpp.

◆ normalize() [4/6]

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

Definition at line 795 of file libxrpl/basics/Number.cpp.

◆ normalize() [5/6]

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

Definition at line 812 of file libxrpl/basics/Number.cpp.

◆ normalize() [6/6]

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

Definition at line 829 of file libxrpl/basics/Number.cpp.

◆ operator==

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

Definition at line 446 of file Number.h.

◆ operator<

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

Definition at line 452 of file Number.h.

◆ operator>

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

Definition at line 504 of file Number.h.

◆ operator<=

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

Definition at line 509 of file Number.h.

◆ operator>=

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

Definition at line 516 of file Number.h.

◆ operator<<

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

Definition at line 521 of file Number.h.

◆ to_string

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

Definition at line 1367 of file libxrpl/basics/Number.cpp.

◆ root

Number root ( Number f,
unsigned d )
friend

Definition at line 1491 of file libxrpl/basics/Number.cpp.

◆ root2

Number root2 ( Number f)
friend

Definition at line 1565 of file libxrpl/basics/Number.cpp.

◆ doNormalize

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

Definition at line 711 of file libxrpl/basics/Number.cpp.

Member Data Documentation

◆ negative_

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

Definition at line 355 of file Number.h.

◆ mantissa_

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

Definition at line 356 of file Number.h.

◆ exponent_

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

Definition at line 357 of file Number.h.

◆ kMinExponent

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

Definition at line 361 of file Number.h.

◆ kMaxExponent

int xrpl::Number::kMaxExponent = 32768
staticconstexpr

Definition at line 362 of file Number.h.

◆ kMaxRep

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

Definition at line 364 of file Number.h.

◆ kMaxRepUp

internalrep xrpl::Number::kMaxRepUp = ((kMaxRep / 10) + 1) * 10
staticconstexpr

Definition at line 367 of file Number.h.

◆ mode

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

Definition at line 598 of file Number.h.

◆ kRange

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

Definition at line 604 of file Number.h.