mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Finish the rewrite.
This commit is contained in:
129
src/Amount.cpp
129
src/Amount.cpp
@@ -420,19 +420,37 @@ STAmount& STAmount::operator=(uint64 v)
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator+=(uint64 v)
|
||||
{ // FIXME
|
||||
if (mIsNative) mValue += v;
|
||||
{
|
||||
if (mIsNative)
|
||||
{
|
||||
if (mIsNegative)
|
||||
*this += STAmount(v);
|
||||
else mValue += v;
|
||||
}
|
||||
else *this += STAmount(mCurrency, v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
STAmount& STAmount::operator-=(uint64 v)
|
||||
{ // FIXME
|
||||
{
|
||||
if (mIsNative)
|
||||
{
|
||||
if (v > mValue)
|
||||
throw std::runtime_error("amount underflow");
|
||||
mValue -= v;
|
||||
if (mIsNegative)
|
||||
{
|
||||
if (v >= mValue)
|
||||
{
|
||||
mIsNegative = false;
|
||||
mValue = v - mValue;
|
||||
}
|
||||
else
|
||||
mValue += v;
|
||||
}
|
||||
else if (v > mValue)
|
||||
{
|
||||
mIsNegative = true;
|
||||
mValue = v - mValue;
|
||||
}
|
||||
else mValue -= v;
|
||||
}
|
||||
else *this -= STAmount(mCurrency, v);
|
||||
return *this;
|
||||
@@ -470,19 +488,28 @@ bool STAmount::operator>=(uint64 v) const
|
||||
}
|
||||
|
||||
STAmount STAmount::operator+(uint64 v) const
|
||||
{ // FIXME
|
||||
{
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error("operation not legal no non-native currency");
|
||||
return STAmount(true, mValue + v);
|
||||
if (mIsNegative)
|
||||
{
|
||||
if (v >= mValue)
|
||||
return STAmount(false, v - mValue); // >=0 result
|
||||
else return STAmount(true, mValue - v); // <0 result
|
||||
}
|
||||
return STAmount(false, mValue + v);
|
||||
}
|
||||
|
||||
STAmount STAmount::operator-(uint64 v) const
|
||||
{ // FIXME
|
||||
{
|
||||
if (!mIsNative)
|
||||
throw std::runtime_error("operation not legal no non-native currency");
|
||||
if (mValue < v)
|
||||
throw std::runtime_error("native currency underflow");
|
||||
return STAmount(true, mValue - v);
|
||||
if (mIsNegative)
|
||||
return STAmount(true, mValue + v);
|
||||
else if (v > mValue) return STAmount(true, v - mValue);
|
||||
return STAmount(false, mValue - v);
|
||||
}
|
||||
|
||||
STAmount::operator double() const
|
||||
@@ -493,53 +520,89 @@ STAmount::operator double() const
|
||||
return static_cast<double>(mValue) * pow(10.0, mOffset);
|
||||
}
|
||||
|
||||
STAmount operator+(STAmount v1, STAmount v2)
|
||||
STAmount operator+(const STAmount& v1, const STAmount& v2)
|
||||
{ // We can check for precision loss here (value%10)!=0
|
||||
// FIXME
|
||||
v1.throwComparable(v2);
|
||||
if (v1.mIsNative)
|
||||
return STAmount(v1.mValue + v2.mValue);
|
||||
{
|
||||
int64 iv1, iv2, s;
|
||||
if (v1.mIsNegative) iv1 = -v1.mValue;
|
||||
else iv1 = v1.mValue;
|
||||
if (v2.mIsNegative) iv2 = -v2.mValue;
|
||||
else iv2 = v2.mValue;
|
||||
s = iv1 + iv2;
|
||||
if (s >= 0) return STAmount(s, false);
|
||||
else return STAmount(-s, true);
|
||||
}
|
||||
|
||||
if (v1.isZero()) return v2;
|
||||
if (v2.isZero()) return v1;
|
||||
|
||||
while (v1.mOffset < v2.mOffset)
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = v1.mValue, vv2 = v2.mValue;
|
||||
if (v1.mIsNegative) vv1 = -vv1;
|
||||
if (v2.mIsNegative) vv2 = -vv2;
|
||||
|
||||
while (ov1 < ov2)
|
||||
{
|
||||
v1.mValue /= 10;
|
||||
++v1.mOffset;
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
while (v2.mOffset < v1.mOffset)
|
||||
while (ov2 < ov1)
|
||||
{
|
||||
v2.mValue /= 10;
|
||||
++v2.mOffset;
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
// this addition cannot overflow a uint64, it can overflow an STAmount and the constructor will throw
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mValue + v2.mValue, v1.mOffset);
|
||||
// this addition cannot overflow an int64, it can overflow an STAmount and the constructor will throw
|
||||
|
||||
int64 fv = vv1 + vv2;
|
||||
if (fv >= 0)
|
||||
return STAmount(v1.name, v1.mCurrency, fv, ov1, false);
|
||||
else
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount operator-(STAmount v1, STAmount v2)
|
||||
STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
{
|
||||
// FIXME
|
||||
v1.throwComparable(v2);
|
||||
if (v2.mIsNative)
|
||||
{
|
||||
if (v2.mValue > v1.mValue)
|
||||
throw std::runtime_error("amount underflow");
|
||||
return STAmount(v1.mValue - v2.mValue);
|
||||
int64 iv1, iv2, s;
|
||||
if (v1.mIsNegative) iv1 = -v1.mValue;
|
||||
else iv1 = v1.mValue;
|
||||
if (v2.mIsNegative) iv2 = -v2.mValue;
|
||||
else iv2 = v2.mValue;
|
||||
s = iv1 - iv2;
|
||||
if (s >= 0) return STAmount(s, false);
|
||||
else return STAmount(-s, true);
|
||||
}
|
||||
if (v2.isZero()) return v1;
|
||||
if (v1.isZero() || (v2.mOffset > v1.mOffset) )
|
||||
throw std::runtime_error("value underflow");
|
||||
|
||||
while (v1.mOffset > v2.mOffset)
|
||||
{
|
||||
v2.mValue /= 10;
|
||||
++v2.mOffset;
|
||||
}
|
||||
if (v1.mValue < v2.mValue)
|
||||
throw std::runtime_error("value underflow");
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = v1.mValue, vv2 = v2.mValue;
|
||||
if (v1.mIsNegative) vv1 = -vv1;
|
||||
if (v2.mIsNegative) vv2 = -vv2;
|
||||
|
||||
return STAmount(v1.name, v1.mCurrency, v1.mValue - v2.mValue, v1.mOffset);
|
||||
while (ov1 < ov2)
|
||||
{
|
||||
vv1 /= 10;
|
||||
++ov1;
|
||||
}
|
||||
while (ov2 < ov1)
|
||||
{
|
||||
vv2 /= 10;
|
||||
++ov2;
|
||||
}
|
||||
// this subtraction cannot overflow an int64, it can overflow an STAmount and the constructor will throw
|
||||
|
||||
int64 fv = vv1 - vv2;
|
||||
if (fv >= 0)
|
||||
return STAmount(v1.name, v1.mCurrency, fv, ov1, false);
|
||||
else
|
||||
return STAmount(v1.name, v1.mCurrency, -fv, ov1, true);
|
||||
}
|
||||
|
||||
STAmount divide(const STAmount& num, const STAmount& den, const uint160& currencyOut)
|
||||
|
||||
@@ -220,21 +220,17 @@ protected:
|
||||
static const uint64 cNotNative = 0x8000000000000000ull;
|
||||
static const uint64 cPosNative = 0x4000000000000000ull;
|
||||
|
||||
STAmount(bool, uint64 value) : mValue(value), mOffset(0), mIsNative(true), mIsNegative(false) { ; }
|
||||
STAmount(bool isNeg, uint64 value) : mValue(value), mOffset(0), mIsNative(true), mIsNegative(isNeg) { ; }
|
||||
|
||||
STAmount(const char *name, uint64 value, bool isNegative)
|
||||
: SerializedType(name), mValue(value), mOffset(0), mIsNative(true), mIsNegative(isNegative)
|
||||
{ ; }
|
||||
|
||||
STAmount(const char *nm, const uint160& cur, uint64 v, int off, bool isNegative)
|
||||
: SerializedType(nm), mCurrency(cur), mValue(v), mOffset(off), mIsNative(false), mIsNegative(isNegative)
|
||||
{ ; }
|
||||
|
||||
uint64 toUInt64() const;
|
||||
|
||||
public:
|
||||
STAmount(uint64 v = 0) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
|
||||
{ ; }
|
||||
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
|
||||
{ if (v==0) mIsNegative = false; }
|
||||
|
||||
STAmount(const char* n, uint64 v = 0)
|
||||
: SerializedType(n), mValue(v), mOffset(0), mIsNative(true), mIsNegative(false)
|
||||
@@ -244,8 +240,8 @@ public:
|
||||
: mCurrency(currency), mValue(v), mOffset(off), mIsNegative(false)
|
||||
{ canonicalize(); }
|
||||
|
||||
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0) : SerializedType(n),
|
||||
mCurrency(currency), mValue(v), mOffset(off), mIsNegative(false)
|
||||
STAmount(const char* n, const uint160& currency, uint64 v = 0, int off = 0, bool isNeg = false) :
|
||||
SerializedType(n), mCurrency(currency), mValue(v), mOffset(off), mIsNegative(isNeg)
|
||||
{ canonicalize(); }
|
||||
|
||||
static std::auto_ptr<SerializedType> deserialize(SerializerIterator& sit, const char* name)
|
||||
@@ -303,8 +299,8 @@ public:
|
||||
|
||||
operator double() const;
|
||||
|
||||
friend STAmount operator+(STAmount v1, STAmount v2);
|
||||
friend STAmount operator-(STAmount v1, STAmount v2);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user