mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Cleanups. Add unit test for STAmount::getRate.
This commit is contained in:
@@ -594,7 +594,7 @@ STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount divide(const STAmount& num, const STAmount& den, const uint160& currencyOut)
|
||||
STAmount STAmount::divide(const STAmount& num, const STAmount& den, const uint160& currencyOut)
|
||||
{
|
||||
if (den.isZero()) throw std::runtime_error("division by zero");
|
||||
if (num.isZero()) return STAmount(currencyOut);
|
||||
@@ -602,10 +602,6 @@ STAmount divide(const STAmount& num, const STAmount& den, const uint160& currenc
|
||||
uint64 numVal = num.mValue, denVal = den.mValue;
|
||||
int numOffset = num.mOffset, denOffset = den.mOffset;
|
||||
|
||||
int finOffset = numOffset - denOffset;
|
||||
if ((finOffset > 80) || (finOffset < 22))
|
||||
throw std::runtime_error("division produces out of range result");
|
||||
|
||||
if (num.mIsNative)
|
||||
while (numVal < STAmount::cMinValue)
|
||||
{ // Need to bring into range
|
||||
@@ -620,6 +616,10 @@ STAmount divide(const STAmount& num, const STAmount& den, const uint160& currenc
|
||||
--denOffset;
|
||||
}
|
||||
|
||||
int finOffset = numOffset - denOffset - 16;
|
||||
if ((finOffset > cMaxOffset) || (finOffset < cMinOffset))
|
||||
throw std::runtime_error("division produces out of range result");
|
||||
|
||||
// Compute (numerator * 10^16) / denominator
|
||||
CBigNum v;
|
||||
if ((BN_add_word(&v, numVal) != 1) ||
|
||||
@@ -633,11 +633,11 @@ STAmount divide(const STAmount& num, const STAmount& den, const uint160& currenc
|
||||
assert(BN_num_bytes(&v) <= 64);
|
||||
|
||||
if (num.mIsNegative != den.mIsNegative)
|
||||
return -STAmount(currencyOut, v.getulong(), numOffset - denOffset - 16);
|
||||
else return STAmount(currencyOut, v.getulong(), numOffset - denOffset - 16);
|
||||
return -STAmount(currencyOut, v.getulong(), finOffset);
|
||||
else return STAmount(currencyOut, v.getulong(), finOffset);
|
||||
}
|
||||
|
||||
STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut)
|
||||
STAmount STAmount::multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut)
|
||||
{
|
||||
if (v1.isZero() || v2.isZero())
|
||||
return STAmount(currencyOut);
|
||||
@@ -699,7 +699,7 @@ STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& currenc
|
||||
else return STAmount(currencyOut, v.getulong(), offset1 + offset2 + 14);
|
||||
}
|
||||
|
||||
uint64 getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
uint64 STAmount::getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
{ // Convert an offer into an index amount so they sort (lower is better)
|
||||
// offerOut = how much comes out of the offer, from the offeror to the taker
|
||||
// offerIn = how much goes into the offer, from the taker to the offeror
|
||||
@@ -711,7 +711,7 @@ uint64 getRate(const STAmount& offerOut, const STAmount& offerIn)
|
||||
return (ret << (64 - 8)) | r.getMantissa();
|
||||
}
|
||||
|
||||
STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
||||
STAmount STAmount::getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
||||
{ // if someone is offering (offerOut) for (offerIn), and I pay (paid), how much do I get?
|
||||
|
||||
offerIn.throwComparable(paid);
|
||||
@@ -748,7 +748,7 @@ STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
||||
return ret;
|
||||
}
|
||||
|
||||
STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
||||
STAmount STAmount::getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
||||
{ // Someone wants to get (needed) out of the offer, how much should they pay in?
|
||||
if (offerOut.isZero()) return STAmount(offerIn.getCurrency());
|
||||
if (needed >= offerOut) return needed;
|
||||
@@ -756,7 +756,7 @@ STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAm
|
||||
return (ret > offerIn) ? offerIn : ret;
|
||||
}
|
||||
|
||||
static uint64 muldiv(uint64 a, uint64 b, uint64 c)
|
||||
uint64 STAmount::muldiv(uint64 a, uint64 b, uint64 c)
|
||||
{ // computes (a*b)/c rounding up - supports values up to 10^18
|
||||
if (c == 0) throw std::runtime_error("underflow");
|
||||
if ((a == 0) || (b == 0)) return 0;
|
||||
@@ -769,12 +769,12 @@ static uint64 muldiv(uint64 a, uint64 b, uint64 c)
|
||||
return v.getulong();
|
||||
}
|
||||
|
||||
uint64 convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit)
|
||||
uint64 STAmount::convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit)
|
||||
{ // Convert an internal ledger/account quantity of native currency to a display amount
|
||||
return muldiv(internalAmount.getNValue(), totalInit, totalNow);
|
||||
}
|
||||
|
||||
STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
|
||||
STAmount STAmount::convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
|
||||
const char *name)
|
||||
{ // Convert a display/request currency amount to an internal amount
|
||||
return STAmount(name, muldiv(displayAmount, totalNow, totalInit));
|
||||
@@ -970,6 +970,31 @@ BOOST_AUTO_TEST_CASE( CustomCurrency_test )
|
||||
BOOST_TEST_MESSAGE("Amount CC Complete");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( CurrencyMulDivTests )
|
||||
{
|
||||
// Test currency multiplication and division operations such as
|
||||
// convertToDisplayAmount, convertToInternalAmount, getRate, getClaimed, and getNeeded
|
||||
|
||||
uint160 c(1);
|
||||
if (STAmount::getRate(STAmount(1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(c, 1), STAmount(c, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(c, 10), STAmount(c, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(c, 1), STAmount(10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(c, 10), STAmount(1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(1), STAmount(c, 10)) != (((100ul-14)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
if (STAmount::getRate(STAmount(10), STAmount(c, 1)) != (((100ul-16)<<(64-8))|1000000000000000ul))
|
||||
BOOST_FAIL("STAmount getrate fail");
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -231,6 +231,7 @@ protected:
|
||||
{ ; }
|
||||
|
||||
uint64 toUInt64() const;
|
||||
static uint64 muldiv(uint64, uint64, uint64);
|
||||
|
||||
public:
|
||||
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
|
||||
@@ -315,22 +316,22 @@ public:
|
||||
friend STAmount operator+(const STAmount& v1, const STAmount& v2);
|
||||
friend STAmount operator-(const STAmount& v1, const STAmount& v2);
|
||||
|
||||
friend STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
friend STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
static STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
static STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& currencyOut);
|
||||
|
||||
// Someone is offering X for Y, what is the rate?
|
||||
friend uint64 getRate(const STAmount& offerOut, const STAmount& offerIn);
|
||||
static uint64 getRate(const STAmount& offerOut, const STAmount& offerIn);
|
||||
|
||||
// Someone is offering X for Y, I try to pay Z, how much do I get?
|
||||
// And what's left of the offer? And how much do I actually pay?
|
||||
friend STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid);
|
||||
static STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid);
|
||||
|
||||
// Someone is offering X for Y, I need Z, how much do I pay
|
||||
friend STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed);
|
||||
static STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed);
|
||||
|
||||
// Native currency conversions, to/from display format
|
||||
friend uint64 convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit);
|
||||
friend STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
|
||||
static uint64 convertToDisplayAmount(const STAmount& internalAmount, uint64 totalNow, uint64 totalInit);
|
||||
static STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
|
||||
const char* name = NULL);
|
||||
|
||||
static STAmount deserialize(SerializerIterator&);
|
||||
|
||||
Reference in New Issue
Block a user