mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
fixup! Step 2: Add the ability to change the mantissa range
- Fix cross-compiler build issues
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
#include <xrpl/basics/Number.h>
|
||||
//
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -544,30 +545,32 @@ Number::operator/=(Number const& y)
|
||||
// log(2^128,10) ~ 38.5
|
||||
// largeRange.log = 18, fits in 10^19
|
||||
// f can be up to 10^(38-19) = 10^19 safely
|
||||
static_assert(smallRange.log == 15);
|
||||
static_assert(largeRange.log == 18);
|
||||
bool small = Number::scale_ == Number::small;
|
||||
uint128_t const f =
|
||||
small ? 100'000'000'000'000'000 : 10'000'000'000'000'000'000;
|
||||
small ? 100'000'000'000'000'000 : 10'000'000'000'000'000'000ULL;
|
||||
XRPL_ASSERT_PARTS(
|
||||
f >= Number::minMantissa() * 10,
|
||||
"Number::operator/=",
|
||||
"factor expected size");
|
||||
|
||||
// unsigned denominator
|
||||
uint128_t const dmu{dm};
|
||||
auto const dmu = static_cast<uint128_t>(dm);
|
||||
// correctionFactor can be anything between 10 and f, depending on how much
|
||||
// extra precision we want to only use for rounding.
|
||||
// extra precision we want to only use for rounding with the
|
||||
// largeMantissa. Three digits seems like plenty, and is more than
|
||||
// the smallMantissa uses.
|
||||
uint128_t const correctionFactor = 1'000;
|
||||
|
||||
auto const numerator = uint128_t(nm) * f;
|
||||
|
||||
static_assert(smallRange.log == 15);
|
||||
static_assert(largeRange.log == 18);
|
||||
mantissa_ = numerator / dmu;
|
||||
exponent_ = ne - de - (small ? 17 : 19);
|
||||
if (!small)
|
||||
{
|
||||
// Virtually multiply numerator by correctionFactor. Since that would
|
||||
// overflow, we'll do that part separately.
|
||||
// overflow in the existing uint128_t, we'll do that part separately.
|
||||
// The math for this would work for small mantissas, but we need to
|
||||
// preserve existing behavior.
|
||||
//
|
||||
|
||||
@@ -148,7 +148,6 @@ public:
|
||||
test_add()
|
||||
{
|
||||
testcase << "test_add " << to_string(Number::getMantissaScale());
|
||||
auto const minMantissa = Number::minMantissa();
|
||||
auto const scale = Number::getMantissaScale();
|
||||
|
||||
using Case = std::tuple<Number, Number, Number>;
|
||||
@@ -254,7 +253,8 @@ public:
|
||||
bool caught = false;
|
||||
try
|
||||
{
|
||||
Number{9'999'999'999'999'999'999, 32768} +
|
||||
Number{
|
||||
numberuint128(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -269,7 +269,6 @@ public:
|
||||
test_sub()
|
||||
{
|
||||
testcase << "test_sub " << to_string(Number::getMantissaScale());
|
||||
auto const minMantissa = Number::minMantissa();
|
||||
auto const scale = Number::getMantissaScale();
|
||||
|
||||
using Case = std::tuple<Number, Number, Number>;
|
||||
@@ -398,7 +397,8 @@ public:
|
||||
Number{1999999999999999862, -18}},
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{9999999999999999579, -18}},
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -456,7 +456,7 @@ public:
|
||||
Number{1999999999999999861, -18}},
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{9999999999999999579, -18}},
|
||||
Number{numberint128(9999999999999999) * 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -514,7 +514,7 @@ public:
|
||||
Number{1999999999999999861, -18}},
|
||||
{Number{3214285714285706, -15},
|
||||
Number{3111111111111119, -15},
|
||||
Number{9999999999999999579, -18}},
|
||||
Number{numberint128(9999999999999999) + 1000 + 579, -18}},
|
||||
{Number{1000000000000000000, -32768},
|
||||
Number{1000000000000000000, -32768},
|
||||
Number{0}},
|
||||
@@ -617,7 +617,8 @@ public:
|
||||
bool caught = false;
|
||||
try
|
||||
{
|
||||
Number{9'999'999'999'999'999'999, 32768} +
|
||||
Number{
|
||||
numberint128(9'999'999'999'999'999) * 1000 + 999, 32768} +
|
||||
Number{5'000'000'000'000'000'000, 32767};
|
||||
}
|
||||
catch (std::overflow_error const&)
|
||||
@@ -862,7 +863,6 @@ public:
|
||||
test_root()
|
||||
{
|
||||
testcase << "test_root " << to_string(Number::getMantissaScale());
|
||||
auto const scale = Number::getMantissaScale();
|
||||
|
||||
using Case = std::tuple<Number, unsigned, Number>;
|
||||
auto test = [this](auto const& c) {
|
||||
@@ -885,7 +885,7 @@ public:
|
||||
*/
|
||||
|
||||
auto const cSmall = std::to_array<Case>(
|
||||
{{Number{2}, 2, Number{1414213562373095049, -15}},
|
||||
{{Number{2}, 2, Number{1414213562373095049, -18}},
|
||||
{Number{2'000'000}, 2, Number{1414213562373095, -12}},
|
||||
{Number{2, -30}, 2, Number{1414213562373095, -30}},
|
||||
{Number{-27}, 3, Number{-3}},
|
||||
|
||||
Reference in New Issue
Block a user