mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
[WIP] Checkpoint
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#ifndef XRPL_BASICS_NUMBER_H_INCLUDED
|
||||
#define XRPL_BASICS_NUMBER_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#endif
|
||||
@@ -41,16 +43,16 @@ isPowerOfTen(T value)
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
using numberuint128 = boost::multiprecision::uint128_t;
|
||||
using numberint128 = boost::multiprecision::int128_t;
|
||||
using numberuint = boost::multiprecision::uint128_t;
|
||||
using numberint = boost::multiprecision::int128_t;
|
||||
#else // !defined(_MSC_VER)
|
||||
using numberuint128 = __uint128_t;
|
||||
using numberint128 = __int128_t;
|
||||
using numberuint = __uint128_t;
|
||||
using numberint = __int128_t;
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
struct MantissaRange
|
||||
{
|
||||
using internalrep = numberint128;
|
||||
using internalrep = numberint;
|
||||
enum mantissa_scale { small, large };
|
||||
|
||||
explicit constexpr MantissaRange(mantissa_scale scale_, internalrep min_)
|
||||
@@ -69,11 +71,14 @@ struct MantissaRange
|
||||
|
||||
class Number
|
||||
{
|
||||
using uint128_t = numberuint128;
|
||||
using int128_t = numberint128;
|
||||
using uint128_t = numberuint;
|
||||
using int128_t = numberint;
|
||||
|
||||
public:
|
||||
using rep = std::int64_t;
|
||||
using internalrep = MantissaRange::internalrep;
|
||||
|
||||
private:
|
||||
internalrep mantissa_{0};
|
||||
int exponent_{std::numeric_limits<int>::lowest()};
|
||||
|
||||
@@ -92,12 +97,9 @@ public:
|
||||
|
||||
Number(rep mantissa);
|
||||
explicit Number(internalrep mantissa, int exponent);
|
||||
explicit constexpr Number(
|
||||
internalrep mantissa,
|
||||
int exponent,
|
||||
unchecked) noexcept;
|
||||
explicit constexpr Number(internalrep mantissa, int exponent, unchecked) noexcept;
|
||||
|
||||
constexpr internalrep
|
||||
constexpr rep
|
||||
mantissa() const noexcept;
|
||||
constexpr int
|
||||
exponent() const noexcept;
|
||||
@@ -125,11 +127,11 @@ public:
|
||||
Number&
|
||||
operator/=(Number const& x);
|
||||
|
||||
static constexpr Number
|
||||
static Number
|
||||
min() noexcept;
|
||||
static constexpr Number
|
||||
static Number
|
||||
max() noexcept;
|
||||
static constexpr Number
|
||||
static Number
|
||||
lowest() noexcept;
|
||||
|
||||
/** Conversions to Number are implicit and conversions away from Number
|
||||
@@ -231,6 +233,15 @@ public:
|
||||
return os << to_string(x);
|
||||
}
|
||||
|
||||
friend std::string
|
||||
to_string(Number const& amount);
|
||||
|
||||
friend Number
|
||||
root(Number f, unsigned d);
|
||||
|
||||
friend Number
|
||||
root2(Number f);
|
||||
|
||||
// Thread local rounding control. Default is to_nearest
|
||||
enum rounding_mode { to_nearest, towards_zero, downward, upward };
|
||||
static rounding_mode
|
||||
@@ -283,21 +294,24 @@ private:
|
||||
static thread_local rounding_mode mode_;
|
||||
// The available ranges for mantissa
|
||||
|
||||
constexpr static internalrep maxRep =
|
||||
std::numeric_limits<std::int64_t>::max();
|
||||
|
||||
constexpr static MantissaRange smallRange{
|
||||
MantissaRange::small,
|
||||
1'000'000'000'000'000LL};
|
||||
static_assert(isPowerOfTen(smallRange.min));
|
||||
static_assert(smallRange.max == 9'999'999'999'999'999LL);
|
||||
static_assert(smallRange.log == 15);
|
||||
// maxint64 9,223,372,036,854,775,808
|
||||
constexpr static MantissaRange largeRange{
|
||||
MantissaRange::large,
|
||||
1'000'000'000'000'000'000LL};
|
||||
static_assert(isPowerOfTen(largeRange.min));
|
||||
// maxRep 9,223,372,036,854,775,808
|
||||
static_assert(largeRange.max == internalrep(9'999'999'999'999'999'999ULL));
|
||||
static_assert(largeRange.log == 18);
|
||||
static_assert(largeRange.min < std::numeric_limits<std::int64_t>::max());
|
||||
static_assert(largeRange.max > std::numeric_limits<std::int64_t>::max());
|
||||
static_assert(largeRange.min < maxRep);
|
||||
static_assert(largeRange.max > maxRep);
|
||||
|
||||
// The range for the mantissa when normalized.
|
||||
// Use reference_wrapper to avoid making copies, and prevent accidentally
|
||||
@@ -314,16 +328,13 @@ private:
|
||||
internalrep const& minMantissa,
|
||||
internalrep const& maxMantissa);
|
||||
|
||||
constexpr bool
|
||||
bool
|
||||
isnormal() const noexcept;
|
||||
|
||||
class Guard;
|
||||
};
|
||||
|
||||
inline constexpr Number::Number(
|
||||
internalrep mantissa,
|
||||
int exponent,
|
||||
unchecked) noexcept
|
||||
inline constexpr Number::Number(internalrep mantissa, int exponent, unchecked) noexcept
|
||||
: mantissa_{mantissa}, exponent_{exponent}
|
||||
{
|
||||
}
|
||||
@@ -338,15 +349,34 @@ inline Number::Number(rep mantissa) : Number{mantissa, 0}
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr Number::internalrep
|
||||
inline
|
||||
constexpr Number::rep
|
||||
Number::mantissa() const noexcept
|
||||
{
|
||||
return mantissa_;
|
||||
auto m = mantissa_;
|
||||
if (m > maxRep)
|
||||
{
|
||||
XRPL_ASSERT_PARTS(
|
||||
m % 10 == 0,
|
||||
"ripple::Number::mantissa",
|
||||
"large mantissa has no remainder");
|
||||
m /= 10;
|
||||
}
|
||||
return static_cast<Number::rep>(m);
|
||||
}
|
||||
|
||||
inline constexpr int
|
||||
inline
|
||||
constexpr int
|
||||
Number::exponent() const noexcept
|
||||
{
|
||||
if (mantissa_ > maxRep)
|
||||
{
|
||||
XRPL_ASSERT_PARTS(
|
||||
mantissa_ % 10 == 0,
|
||||
"ripple::Number::exponent",
|
||||
"large mantissa has no remainder");
|
||||
return exponent_ + 1;
|
||||
}
|
||||
return exponent_;
|
||||
}
|
||||
|
||||
@@ -432,25 +462,25 @@ operator/(Number const& x, Number const& y)
|
||||
return z;
|
||||
}
|
||||
|
||||
inline constexpr Number
|
||||
inline Number
|
||||
Number::min() noexcept
|
||||
{
|
||||
return Number{range_.get().min, minExponent, unchecked{}};
|
||||
}
|
||||
|
||||
inline constexpr Number
|
||||
inline Number
|
||||
Number::max() noexcept
|
||||
{
|
||||
return Number{range_.get().max, maxExponent, unchecked{}};
|
||||
}
|
||||
|
||||
inline constexpr Number
|
||||
inline Number
|
||||
Number::lowest() noexcept
|
||||
{
|
||||
return -Number{range_.get().max, maxExponent, unchecked{}};
|
||||
}
|
||||
|
||||
inline constexpr bool
|
||||
inline bool
|
||||
Number::isnormal() const noexcept
|
||||
{
|
||||
MantissaRange const& range = range_;
|
||||
|
||||
Reference in New Issue
Block a user