mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-05 01:37:00 +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_;
|
||||
|
||||
@@ -21,12 +21,12 @@ using uint128_t = boost::multiprecision::uint128_t;
|
||||
#else // !defined(_MSC_VER)
|
||||
using uint128_t = __uint128_t;
|
||||
#endif // !defined(_MSC_VER)
|
||||
static_assert(std::is_same_v<uint128_t, ripple::numberuint128>);
|
||||
static_assert(std::is_same_v<uint128_t, ripple::numberuint>);
|
||||
|
||||
namespace std {
|
||||
|
||||
template <>
|
||||
struct make_unsigned<ripple::numberint128>
|
||||
struct make_unsigned<ripple::numberint>
|
||||
{
|
||||
using type = uint128_t;
|
||||
};
|
||||
@@ -256,13 +256,36 @@ Number::normalize(
|
||||
m /= 10;
|
||||
++exponent_;
|
||||
}
|
||||
mantissa_ = m;
|
||||
if ((exponent_ < minExponent) || (mantissa_ < minMantissa))
|
||||
if ((exponent_ < minExponent) || (m < minMantissa))
|
||||
{
|
||||
mantissa_ = zero.mantissa_;
|
||||
exponent_ = zero.exponent_;
|
||||
return;
|
||||
}
|
||||
// When using the largeRange, m needs fit within an int64, even if
|
||||
// the final mantissa_ is going to end up larger to fit within the range.
|
||||
// Cut it down here so that the rounding will be done while it's smaller.
|
||||
//
|
||||
// Example: 9,900,000,000,000,555,555 > 9,223,372,036,854,775,808,
|
||||
// so m will end up a 990,000,000,000,055,555. Then that value will be
|
||||
// rounded to 990,000,000,000,055,555 or 990,000,000,000,055,556.
|
||||
// mantissa_ will be m*10 so it fits within the range, and end up as
|
||||
// 9,900,000,000,000,555,550 or 9,900,000,000,000,555,560.
|
||||
// mantissa() will return mantissa_ / 10, and exponent() will return
|
||||
// exponent_ + 1.
|
||||
if (m > maxRep)
|
||||
{
|
||||
if (exponent_ >= maxExponent)
|
||||
throw std::overflow_error("Number::normalize 1.5");
|
||||
g.push(m % 10);
|
||||
m /= 10;
|
||||
++exponent_;
|
||||
}
|
||||
XRPL_ASSERT_PARTS(
|
||||
m <= maxRep,
|
||||
"ripple::Number::normalize",
|
||||
"intermediate mantissa fits in int64");
|
||||
mantissa_ = m;
|
||||
|
||||
auto r = g.round();
|
||||
if (r == 1 || (r == 0 && (mantissa_ & 1) == 1))
|
||||
@@ -276,6 +299,18 @@ Number::normalize(
|
||||
}
|
||||
if (exponent_ > maxExponent)
|
||||
throw std::overflow_error("Number::normalize 2");
|
||||
if (mantissa_ < minMantissa)
|
||||
{
|
||||
// When using the largeRange, the intermediate M needs fit within an
|
||||
// int64, but mantissa_ needs to fit within the minMantissa /
|
||||
// maxMantissa range.
|
||||
mantissa_ *= 10;
|
||||
--exponent_;
|
||||
}
|
||||
XRPL_ASSERT_PARTS(
|
||||
mantissa_ >= minMantissa && mantissa_ <= maxMantissa,
|
||||
"ripple::Number::normalize",
|
||||
"final mantissa fits in range");
|
||||
|
||||
if (negative)
|
||||
mantissa_ = -mantissa_;
|
||||
@@ -306,16 +341,16 @@ Number::operator+=(Number const& y)
|
||||
XRPL_ASSERT(
|
||||
isnormal() && y.isnormal(),
|
||||
"ripple::Number::operator+=(Number) : is normal");
|
||||
auto xm = mantissa();
|
||||
auto xe = exponent();
|
||||
auto xm = mantissa_;
|
||||
auto xe = exponent_;
|
||||
int xn = 1;
|
||||
if (xm < 0)
|
||||
{
|
||||
xm = -xm;
|
||||
xn = -1;
|
||||
}
|
||||
auto ym = y.mantissa();
|
||||
auto ye = y.exponent();
|
||||
auto ym = y.mantissa_;
|
||||
auto ye = y.exponent_;
|
||||
int yn = 1;
|
||||
if (ym < 0)
|
||||
{
|
||||
@@ -451,16 +486,16 @@ Number::operator*=(Number const& y)
|
||||
XRPL_ASSERT(
|
||||
isnormal() && y.isnormal(),
|
||||
"ripple::Number::operator*=(Number) : is normal");
|
||||
auto xm = mantissa();
|
||||
auto xe = exponent();
|
||||
auto xm = mantissa_;
|
||||
auto xe = exponent_;
|
||||
int xn = 1;
|
||||
if (xm < 0)
|
||||
{
|
||||
xm = -xm;
|
||||
xn = -1;
|
||||
}
|
||||
auto ym = y.mantissa();
|
||||
auto ye = y.exponent();
|
||||
auto ym = y.mantissa_;
|
||||
auto ye = y.exponent_;
|
||||
int yn = 1;
|
||||
if (ym < 0)
|
||||
{
|
||||
@@ -521,16 +556,16 @@ Number::operator/=(Number const& y)
|
||||
if (*this == Number{})
|
||||
return *this;
|
||||
int np = 1;
|
||||
auto nm = mantissa();
|
||||
auto ne = exponent();
|
||||
auto nm = mantissa_;
|
||||
auto ne = exponent_;
|
||||
if (nm < 0)
|
||||
{
|
||||
nm = -nm;
|
||||
np = -1;
|
||||
}
|
||||
int dp = 1;
|
||||
auto dm = y.mantissa();
|
||||
auto de = y.exponent();
|
||||
auto dm = y.mantissa_;
|
||||
auto de = y.exponent_;
|
||||
if (dm < 0)
|
||||
{
|
||||
dm = -dm;
|
||||
@@ -649,12 +684,12 @@ to_string(Number const& amount)
|
||||
if (amount == Number{})
|
||||
return "0";
|
||||
|
||||
auto const exponent = amount.exponent();
|
||||
auto const exponent = amount.exponent_;
|
||||
|
||||
bool const negative = amount.mantissa() < 0;
|
||||
bool const negative = amount.mantissa_ < 0;
|
||||
|
||||
auto const mantissa = [&]() {
|
||||
auto mantissa = amount.mantissa();
|
||||
auto mantissa = amount.mantissa_;
|
||||
if (negative)
|
||||
{
|
||||
mantissa = -mantissa;
|
||||
@@ -806,7 +841,7 @@ root(Number f, unsigned d)
|
||||
return di - k2;
|
||||
}();
|
||||
e += ex;
|
||||
f = Number{f.mantissa(), f.exponent() - e}; // f /= 10^e;
|
||||
f = Number{f.mantissa_, f.exponent_ - e}; // f /= 10^e;
|
||||
bool neg = false;
|
||||
if (f < Number{})
|
||||
{
|
||||
@@ -838,7 +873,7 @@ root(Number f, unsigned d)
|
||||
} while (r != rm1 && r != rm2);
|
||||
|
||||
// return r * 10^(e/d) to reverse scaling
|
||||
return Number{r.mantissa(), r.exponent() + e / di};
|
||||
return Number{r.mantissa_, r.exponent_ + e / di};
|
||||
}
|
||||
|
||||
Number
|
||||
@@ -857,7 +892,7 @@ root2(Number f)
|
||||
auto e = f.exponent() + Number::mantissaLog() + 1;
|
||||
if (e % 2 != 0)
|
||||
++e;
|
||||
f = Number{f.mantissa(), f.exponent() - e}; // f /= 10^e;
|
||||
f = Number{f.mantissa_, f.exponent_ - e}; // f /= 10^e;
|
||||
|
||||
// Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
|
||||
auto const D = 105;
|
||||
@@ -878,7 +913,7 @@ root2(Number f)
|
||||
} while (r != rm1 && r != rm2);
|
||||
|
||||
// return r * 10^(e/2) to reverse scaling
|
||||
return Number{r.mantissa(), r.exponent() + e / 2};
|
||||
return Number{r.mantissa_, r.exponent_ + e / 2};
|
||||
}
|
||||
|
||||
// Returns f^(n/d)
|
||||
|
||||
@@ -202,7 +202,7 @@ numberFromJson(SField const& field, Json::Value const& value)
|
||||
// Number mantissas are much bigger than the allowable parsed values, so
|
||||
// it can't be out of range.
|
||||
static_assert(
|
||||
std::numeric_limits<numberint128>::max() >
|
||||
std::numeric_limits<numberint>::max() >
|
||||
std::numeric_limits<decltype(parts.mantissa)>::max());
|
||||
}
|
||||
else
|
||||
@@ -210,7 +210,7 @@ numberFromJson(SField const& field, Json::Value const& value)
|
||||
Throw<std::runtime_error>("not a number");
|
||||
}
|
||||
|
||||
numberint128 mantissa = parts.mantissa;
|
||||
numberint mantissa = parts.mantissa;
|
||||
if (parts.negative)
|
||||
mantissa = -mantissa;
|
||||
|
||||
|
||||
@@ -120,12 +120,12 @@ public:
|
||||
|
||||
test(
|
||||
Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999,
|
||||
numberuint(9'999'999'999'999'999) * 1000 + 999,
|
||||
-3},
|
||||
"9999999999999999");
|
||||
test(
|
||||
-(Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999,
|
||||
numberuint(9'999'999'999'999'999) * 1000 + 999,
|
||||
-3}),
|
||||
"-9999999999999999");
|
||||
}
|
||||
@@ -149,14 +149,14 @@ public:
|
||||
|
||||
test(
|
||||
Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999,
|
||||
numberuint(9'999'999'999'999'999) * 1000 + 999,
|
||||
0},
|
||||
"9999999999999999999");
|
||||
"9999999999999999990");
|
||||
test(
|
||||
-(Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999,
|
||||
numberuint(9'999'999'999'999'999) * 1000 + 999,
|
||||
0}),
|
||||
"-9999999999999999999");
|
||||
"-9999999999999999990");
|
||||
}
|
||||
break;
|
||||
break;
|
||||
@@ -206,10 +206,10 @@ public:
|
||||
{Number{-1'000'000'000'000'000, -15},
|
||||
Number{6'555'555'555'555'555, -29},
|
||||
Number{
|
||||
-(numberint128(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
-(numberint(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
{Number{-6'555'555'555'555'555, -29},
|
||||
Number{1'000'000'000'000'000, -15},
|
||||
Number{numberint128(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
Number{numberint(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
{Number{}, Number{5}, Number{5}},
|
||||
{Number{5}, Number{}, Number{5}},
|
||||
{Number{5'555'555'555'555'555'000, -32768},
|
||||
@@ -228,17 +228,17 @@ public:
|
||||
{Number{-1'000'000'000'000'000'000, -18},
|
||||
Number{6'555'555'555'555'555'555, -35},
|
||||
Number{
|
||||
-(numberint128(9'999'999'999'999'999) * 1'000 + 344), -19}},
|
||||
-(numberint(9'999'999'999'999'999) * 1'000 + 344), -19}},
|
||||
{Number{-6'555'555'555'555'555'555, -35},
|
||||
Number{1'000'000'000'000'000'000, -18},
|
||||
Number{numberint128(9'999'999'999'999'999) * 1'000 + 344, -19}},
|
||||
Number{numberint(9'999'999'999'999'999) * 1'000 + 344, -19}},
|
||||
{Number{}, Number{5}, Number{5}},
|
||||
{Number{5'555'555'555'555'555'555, -32768},
|
||||
Number{-5'555'555'555'555'555'554, -32768},
|
||||
Number{0}},
|
||||
{Number{-(numberint128(9'999'999'999'999'999) * 1'000 + 999), -37},
|
||||
{Number{-(numberint(9'999'999'999'999'999) * 1'000 + 999), -37},
|
||||
Number{1'000'000'000'000'000'000, -18},
|
||||
Number{numberint128(9'999'999'999'999'999) * 1'000 + 990, -19}}});
|
||||
Number{numberint(9'999'999'999'999'999) * 1'000 + 990, -19}}});
|
||||
auto test = [this](auto const& c) {
|
||||
for (auto const& [x, y, z] : c)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ public:
|
||||
Number{9'999'999'999'999'999, 32768} +
|
||||
Number{5'000'000'000'000'000, 32767};
|
||||
else
|
||||
Number{numberint128(9'999'999'999'999'999) * 1'000, 32768} +
|
||||
Number{numberint(9'999'999'999'999'999) * 1'000, 32768} +
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -275,7 +275,7 @@ public:
|
||||
try
|
||||
{
|
||||
Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
numberuint(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -315,11 +315,11 @@ public:
|
||||
// with larger mantissa
|
||||
{{Number{1'000'000'000'000'000, -15},
|
||||
Number{6'555'555'555'555'555, -29},
|
||||
Number{numberint128(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
Number{numberint(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
{Number{6'555'555'555'555'555, -29},
|
||||
Number{1'000'000'000'000'000, -15},
|
||||
Number{
|
||||
-(numberint128(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
-(numberint(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
{Number{1'000'000'000'000'000, -15},
|
||||
Number{1'000'000'000'000'000, -15},
|
||||
Number{0}},
|
||||
@@ -332,11 +332,11 @@ public:
|
||||
// Items from cSmall expanded for the larger mantissa
|
||||
{Number{1'000'000'000'000'000'000, -18},
|
||||
Number{6'555'555'555'555'555'555, -32},
|
||||
Number{numberint128(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
Number{numberint(9'999'999'999'999'344) * 1'000 + 444, -19}},
|
||||
{Number{6'555'555'555'555'555'555, -32},
|
||||
Number{1'000'000'000'000'000'000, -18},
|
||||
Number{
|
||||
-(numberint128(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
-(numberint(9'999'999'999'999'344) * 1'000 + 444), -19}},
|
||||
{Number{1'000'000'000'000'000'000, -18},
|
||||
Number{1'000'000'000'000'000'000, -18},
|
||||
Number{0}},
|
||||
@@ -423,7 +423,7 @@ public:
|
||||
Number{1999999999999999862, -18}},
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{numberint128(9'999'999'999'999'999) * 1000 + 579, -18}},
|
||||
Number{numberint(9'999'999'999'999'999) * 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -443,9 +443,9 @@ public:
|
||||
Number{3111111111111111119, -18},
|
||||
Number{10, 0}},
|
||||
// Maximum mantissa range
|
||||
{Number{numberint128(9'999'999'999'999'999) * 1000 + 999, 0},
|
||||
Number{numberint128(9'999'999'999'999'999) * 1000 + 999, 0},
|
||||
Number{numberint128(9'999'999'999'999'999) * 1000 + 998, 19}},
|
||||
{Number{numberint(9'999'999'999'999'999) * 1000 + 999, 0},
|
||||
Number{numberint(9'999'999'999'999'999) * 1000 + 999, 0},
|
||||
Number{numberint(9'999'999'999'999'999) * 1000 + 998, 19}},
|
||||
});
|
||||
tests(cSmall, cLarge);
|
||||
}
|
||||
@@ -486,7 +486,7 @@ public:
|
||||
Number{1999999999999999861, -18}},
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{numberint128(9999999999999999) * 1000 + 579, -18}},
|
||||
Number{numberint(9999999999999999) * 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -545,7 +545,7 @@ public:
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1000 + 579, -18}},
|
||||
numberint(9'999'999'999'999'999) * 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -634,7 +634,7 @@ public:
|
||||
Number{9'999'999'999'999'999, 32768} *
|
||||
Number{5'000'000'000'000'000, 32767};
|
||||
else
|
||||
Number{numberint128(9'999'999'999'999'999) * 1'000, 32768} *
|
||||
Number{numberint(9'999'999'999'999'999) * 1'000, 32768} *
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -649,7 +649,7 @@ public:
|
||||
try
|
||||
{
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
numberint(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -722,10 +722,10 @@ public:
|
||||
{Number{1414213562373095049, -13},
|
||||
Number{1414213562373095049, -13},
|
||||
Number{1}},
|
||||
{Number{numberint128(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
{Number{numberint(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
Number{1'000'000'000'000'000'000},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1'000 + 999,
|
||||
numberint(9'999'999'999'999'999) * 1'000 + 999,
|
||||
-18}}});
|
||||
tests(cSmall, cLarge);
|
||||
}
|
||||
@@ -771,10 +771,10 @@ public:
|
||||
{Number{1414213562373095049, -13},
|
||||
Number{1414213562373095049, -13},
|
||||
Number{1}},
|
||||
{Number{numberint128(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
{Number{numberint(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
Number{1'000'000'000'000'000'000},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1'000 + 999,
|
||||
numberint(9'999'999'999'999'999) * 1'000 + 999,
|
||||
-18}}});
|
||||
tests(cSmall, cLarge);
|
||||
}
|
||||
@@ -820,10 +820,10 @@ public:
|
||||
{Number{1414213562373095049, -13},
|
||||
Number{1414213562373095049, -13},
|
||||
Number{1}},
|
||||
{Number{numberint128(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
{Number{numberint(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
Number{1'000'000'000'000'000'000},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1'000 + 999,
|
||||
numberint(9'999'999'999'999'999) * 1'000 + 999,
|
||||
-18}}});
|
||||
tests(cSmall, cLarge);
|
||||
}
|
||||
@@ -869,10 +869,10 @@ public:
|
||||
{Number{1414213562373095049, -13},
|
||||
Number{1414213562373095049, -13},
|
||||
Number{1}},
|
||||
{Number{numberint128(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
{Number{numberint(9'999'999'999'999'999) * 1'000 + 999, 0},
|
||||
Number{1'000'000'000'000'000'000},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1'000 + 999,
|
||||
numberint(9'999'999'999'999'999) * 1'000 + 999,
|
||||
-18}}});
|
||||
tests(cSmall, cLarge);
|
||||
}
|
||||
@@ -1002,10 +1002,10 @@ public:
|
||||
{Number{-64}, 3, Number{-262144}},
|
||||
{Number{64},
|
||||
11,
|
||||
Number{numberint128(73786976294838206) * 1000 + 464, 0}},
|
||||
Number{numberint(73786976294838206) * 1000 + 464, 0}},
|
||||
{Number{-64},
|
||||
11,
|
||||
Number{-(numberint128(73786976294838206) * 1000 + 464), 0}}};
|
||||
Number{-(numberint(73786976294838206) * 1000 + 464), 0}}};
|
||||
for (auto const& [x, y, z] : c)
|
||||
BEAST_EXPECT((power(x, y) == z));
|
||||
}
|
||||
@@ -1393,7 +1393,7 @@ public:
|
||||
// 99999999999999999980000000000000000001 - also 38 digits
|
||||
BEAST_EXPECT(
|
||||
(power(max, 2) ==
|
||||
Number{numberint128(9'999'999'999'999'999) * 1000 + 998, 19}));
|
||||
Number{numberint(9'999'999'999'999'999) * 1000 + 998, 19}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ struct STNumber_test : public beast::unit_test::suite
|
||||
STNumber(
|
||||
sfNumber,
|
||||
-Number{
|
||||
numberint128(9'223'372'036'854'775) * 1000 +
|
||||
numberint(9'223'372'036'854'775) * 1000 +
|
||||
808,
|
||||
0}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user