mirror of
https://github.com/XRPLF/rippled.git
synced 2026-07-25 16:10:57 +00:00
Expand Number to support the full integer range (#6025)
- Refactor Number internals away from int64 to uint64 & a sign flag
- ctors and accessors use `rep`. Very few things expose
`internalrep`.
- An exception is "unchecked" and the new "normalized", which explicitly
take an internalrep. But with those special control flags, it's easier
to distinguish and control when they are used.
- For now, skip the larger mantissas in AMM transactions and tests
- Remove trailing zeros from scientific notation Number strings
- Update tests. This has the happy side effect of making some of the string
representations _more_ consistent between the small and large
mantissa ranges.
- Add semi-automatic rounding of STNumbers based on Asset types
- Create a new SField metadata enum, sMD_NeedsAsset, which indicates
the field should be associated with an Asset so it can be rounded.
- Add a new STTakesAsset intermediate class to handle the Asset
association to a derived ST class. Currently only used in STNumber,
but could be used by other types in the future.
- Add "associateAsset" which takes an SLE and an Asset, finds the
sMD_NeedsAsset fields, and associates the Asset to them. In the case
of STNumber, that both stores the Asset, and rounds the value
immediately.
- Transactors only need to add a call to associateAsset _after_ all of
the STNumbers have been set. Unfortunately, the inner workings of
STObject do not do the association correctly with uninitialized
fields.
- When serializing an STNumber that has an Asset, round it before
serializing.
- Add an override of roundToAsset, which rounds a Number value in place
to an Asset, but without any additional scale.
- Update and fix a bunch of Loan-related tests to accommodate the
expanded Number class.
---------
Co-authored-by: Vito <5780819+Tapanito@users.noreply.github.com>
This commit is contained in:
@@ -29,10 +29,8 @@ struct STNumber_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
doRun()
|
||||
{
|
||||
static_assert(!std::is_convertible_v<STNumber*, Number*>);
|
||||
|
||||
{
|
||||
STNumber const stnum{sfNumber};
|
||||
BEAST_EXPECT(stnum.getSType() == STI_NUMBER);
|
||||
@@ -127,6 +125,41 @@ struct STNumber_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, "-0.000e6") == STNumber(sfNumber, 0));
|
||||
|
||||
{
|
||||
NumberRoundModeGuard mg(Number::towards_zero);
|
||||
// maxint64 9,223,372,036,854,775,807
|
||||
auto const maxInt =
|
||||
std::to_string(std::numeric_limits<std::int64_t>::max());
|
||||
// minint64 -9,223,372,036,854,775,808
|
||||
auto const minInt =
|
||||
std::to_string(std::numeric_limits<std::int64_t>::min());
|
||||
if (Number::getMantissaScale() == MantissaRange::small)
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, maxInt) ==
|
||||
STNumber(sfNumber, Number{9'223'372'036'854'775, 3}));
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, minInt) ==
|
||||
STNumber(sfNumber, Number{-9'223'372'036'854'775, 3}));
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, maxInt) ==
|
||||
STNumber(
|
||||
sfNumber, Number{9'223'372'036'854'775'807, 0}));
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, minInt) ==
|
||||
STNumber(
|
||||
sfNumber,
|
||||
Number{
|
||||
true,
|
||||
9'223'372'036'854'775'808ULL,
|
||||
0,
|
||||
Number::normalized{}}));
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto imin = std::numeric_limits<int>::min();
|
||||
BEAST_EXPECT(
|
||||
numberFromJson(sfNumber, imin) ==
|
||||
@@ -279,15 +312,21 @@ struct STNumber_test : public beast::unit_test::suite
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
static_assert(!std::is_convertible_v<STNumber*, Number*>);
|
||||
|
||||
for (auto const scale : {MantissaRange::small, MantissaRange::large})
|
||||
{
|
||||
NumberMantissaScaleGuard sg(scale);
|
||||
testcase << to_string(Number::getMantissaScale());
|
||||
doRun();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(STNumber, protocol, xrpl);
|
||||
|
||||
void
|
||||
testCompile(std::ostream& out)
|
||||
{
|
||||
STNumber number{sfNumber, 42};
|
||||
out << number;
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
Reference in New Issue
Block a user