rippled
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Static Private Attributes | Friends | List of all members
xrpl::Number Class Reference

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

#include <Number.h>

Collaboration diagram for xrpl::Number:
Collaboration graph
[legend]

Classes

class  Guard
 
struct  normalized
 
struct  unchecked
 

Public Types

enum  rounding_mode { to_nearest , towards_zero , 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<Integral64 T>
std::pair< T, int > normalizeToRange (T minMantissa, T maxMantissa) const
 

Static Public Member Functions

static Number min () noexcept
 
static Number max () noexcept
 
static Number lowest () noexcept
 
static rounding_mode getround ()
 
static rounding_mode setround (rounding_mode mode)
 
static MantissaRange::mantissa_scale getMantissaScale ()
 Returns which mantissa scale is currently in use for normalization.
 
static void setMantissaScale (MantissaRange::mantissa_scale scale)
 Changes which mantissa scale is used for normalization.
 
static internalrep minMantissa ()
 
static internalrep maxMantissa ()
 
static int mantissaLog ()
 
static constexpr Number oneSmall ()
 oneSmall is needed because the ranges are private
 
static constexpr Number oneLarge ()
 oneLarge is needed because the ranges are private
 
static Number one ()
 

Static Public Attributes

static constexpr int minExponent = -32768
 
static constexpr int maxExponent = 32768
 
static constexpr internalrep maxRep = std::numeric_limits<rep>::max()
 

Private Types

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

Private Member Functions

void normalize ()
 
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)
 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)
 
template<>
void normalize (bool &negative, unsigned long long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa)
 
template<>
void normalize (bool &negative, unsigned long &mantissa, int &exponent, internalrep const &minMantissa, internalrep const &maxMantissa)
 

Private Attributes

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

Static Private Attributes

static thread_local rounding_mode mode_ = Number::to_nearest
 
static constexpr MantissaRange smallRange {MantissaRange::small}
 
static constexpr MantissaRange largeRange {MantissaRange::large}
 
static thread_local std::reference_wrapper< MantissaRange const > range_ = largeRange
 

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 &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
 
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)
 

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 206 of file Number.h.

Member Typedef Documentation

◆ rep

Definition at line 208 of file Number.h.

◆ internalrep

Definition at line 209 of file Number.h.

Member Enumeration Documentation

◆ rounding_mode

Enumerator
to_nearest 
towards_zero 
downward 
upward 

Definition at line 380 of file Number.h.

Constructor & Destructor Documentation

◆ Number() [1/7]

constexpr xrpl::Number::Number ( )
explicitconstexprdefault

◆ Number() [2/7]

xrpl::Number::Number ( rep  mantissa)

Definition at line 532 of file Number.h.

◆ Number() [3/7]

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

Definition at line 527 of file Number.h.

◆ Number() [4/7]

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

Definition at line 505 of file Number.h.

◆ Number() [5/7]

constexpr xrpl::Number::Number ( internalrep  mantissa,
int  exponent,
unchecked   
)
explicitconstexprnoexcept

Definition at line 510 of file Number.h.

◆ Number() [6/7]

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

Definition at line 517 of file Number.h.

◆ Number() [7/7]

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

Definition at line 523 of file Number.h.

Member Function Documentation

◆ mantissa()

constexpr Number::rep xrpl::Number::mantissa ( ) const
constexprnoexcept

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 542 of file Number.h.

◆ exponent()

constexpr int xrpl::Number::exponent ( ) const
constexprnoexcept

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 563 of file Number.h.

◆ operator+()

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

Definition at line 578 of file Number.h.

◆ operator-()

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

Definition at line 584 of file Number.h.

◆ operator++() [1/2]

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

Definition at line 594 of file Number.h.

◆ operator++() [2/2]

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

Definition at line 601 of file Number.h.

◆ operator--() [1/2]

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

Definition at line 609 of file Number.h.

◆ operator--() [2/2]

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

Definition at line 616 of file Number.h.

◆ operator+=()

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

Definition at line 497 of file Number.cpp.

◆ operator-=()

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

Definition at line 624 of file Number.h.

◆ operator*=()

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

Definition at line 624 of file Number.cpp.

◆ operator/=()

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

Definition at line 682 of file Number.cpp.

◆ min()

Number xrpl::Number::min ( )
staticnoexcept

Definition at line 662 of file Number.h.

◆ max()

Number xrpl::Number::max ( )
staticnoexcept

Definition at line 668 of file Number.h.

◆ lowest()

Number xrpl::Number::lowest ( )
staticnoexcept

Definition at line 674 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 776 of file Number.cpp.

◆ signum()

constexpr int xrpl::Number::signum ( ) const
constexprnoexcept

Return the sign of the amount.

Definition at line 338 of file Number.h.

◆ truncate()

Number xrpl::Number::truncate ( ) const
noexcept

Definition at line 805 of file Number.cpp.

◆ getround()

Number::rounding_mode xrpl::Number::getround ( )
static

Definition at line 33 of file Number.cpp.

◆ setround()

Number::rounding_mode xrpl::Number::setround ( rounding_mode  mode)
static

Definition at line 39 of file Number.cpp.

◆ getMantissaScale()

MantissaRange::mantissa_scale 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 45 of file Number.cpp.

◆ setMantissaScale()

void xrpl::Number::setMantissaScale ( MantissaRange::mantissa_scale  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 51 of file Number.cpp.

◆ minMantissa()

static internalrep xrpl::Number::minMantissa ( )
static

Definition at line 401 of file Number.h.

◆ maxMantissa()

static internalrep xrpl::Number::maxMantissa ( )
static

Definition at line 407 of file Number.h.

◆ mantissaLog()

static int xrpl::Number::mantissaLog ( )
static

Definition at line 413 of file Number.h.

◆ oneSmall()

constexpr Number xrpl::Number::oneSmall ( )
staticconstexpr

oneSmall is needed because the ranges are private

Definition at line 327 of file Number.cpp.

◆ oneLarge()

constexpr Number xrpl::Number::oneLarge ( )
staticconstexpr

oneLarge is needed because the ranges are private

Definition at line 335 of file Number.cpp.

◆ one()

Number xrpl::Number::one ( )
static

Definition at line 343 of file Number.cpp.

◆ normalizeToRange()

template<Integral64 T>
std::pair< T, int > xrpl::Number::normalizeToRange ( minMantissa,
maxMantissa 
) const

Definition at line 691 of file Number.h.

◆ normalize() [1/5]

void xrpl::Number::normalize ( )
private

Definition at line 471 of file Number.cpp.

◆ normalize() [2/5]

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

Normalize Number components to an arbitrary range.

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

◆ isnormal()

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

Definition at line 680 of file Number.h.

◆ shiftExponent()

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

Definition at line 481 of file Number.cpp.

◆ externalToInternal()

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

Definition at line 308 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 
)
staticprivate

Definition at line 435 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 
)
staticprivate

Definition at line 447 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 
)
staticprivate

Definition at line 459 of file Number.cpp.

Friends And Related Symbol Documentation

◆ operator==

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

Definition at line 295 of file Number.h.

◆ operator!=

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

Definition at line 301 of file Number.h.

◆ operator<

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

Definition at line 306 of file Number.h.

◆ operator>

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

Definition at line 347 of file Number.h.

◆ operator<=

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

Definition at line 352 of file Number.h.

◆ operator>=

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

Definition at line 359 of file Number.h.

◆ operator<<

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

Definition at line 364 of file Number.h.

◆ to_string

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

Definition at line 823 of file Number.cpp.

◆ root

Number root ( Number  f,
unsigned  d 
)
friend

Definition at line 938 of file Number.cpp.

◆ root2

Number root2 ( Number  f)
friend

Definition at line 1010 of file Number.cpp.

◆ doNormalize

template<class T >
void doNormalize ( bool &  negative,
T &  mantissa_,
int &  exponent_,
MantissaRange::rep const &  minMantissa,
MantissaRange::rep const &  maxMantissa 
)
friend

Definition at line 355 of file Number.cpp.

Member Data Documentation

◆ negative_

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

Definition at line 211 of file Number.h.

◆ mantissa_

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

Definition at line 212 of file Number.h.

◆ exponent_

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

Definition at line 213 of file Number.h.

◆ minExponent

constexpr int xrpl::Number::minExponent = -32768
staticconstexpr

Definition at line 217 of file Number.h.

◆ maxExponent

constexpr int xrpl::Number::maxExponent = 32768
staticconstexpr

Definition at line 218 of file Number.h.

◆ maxRep

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

Definition at line 220 of file Number.h.

◆ mode_

thread_local Number::rounding_mode xrpl::Number::mode_ = Number::to_nearest
staticprivate

Definition at line 436 of file Number.h.

◆ smallRange

constexpr MantissaRange xrpl::Number::smallRange {MantissaRange::small}
staticconstexprprivate

Definition at line 439 of file Number.h.

◆ largeRange

constexpr MantissaRange xrpl::Number::largeRange {MantissaRange::large}
staticconstexprprivate

Definition at line 446 of file Number.h.

◆ range_

thread_local std::reference_wrapper< MantissaRange const > xrpl::Number::range_ = largeRange
staticprivate

Definition at line 457 of file Number.h.