mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Fix some special cases. Cleanup whitespace.
This commit is contained in:
150
src/Amount.cpp
150
src/Amount.cpp
@@ -13,26 +13,28 @@
|
|||||||
|
|
||||||
void STAmount::canonicalize()
|
void STAmount::canonicalize()
|
||||||
{
|
{
|
||||||
if(value==0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
offset=0;
|
offset=0;
|
||||||
value=0;
|
value=0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while(value<cMinValue)
|
while(value < cMinValue)
|
||||||
{
|
{
|
||||||
if(offset<=cMinOffset) throw std::runtime_error("value overflow");
|
if (offset <= cMinOffset)
|
||||||
value*=10;
|
throw std::runtime_error("value overflow");
|
||||||
|
value *= 10;
|
||||||
--offset;
|
--offset;
|
||||||
}
|
}
|
||||||
while(value>cMaxValue)
|
while(value > cMaxValue)
|
||||||
{
|
{
|
||||||
if(offset>=cMaxOffset) throw std::runtime_error("value underflow");
|
if (offset >= cMaxOffset)
|
||||||
value/=10;
|
throw std::runtime_error("value underflow");
|
||||||
|
value /= 10;
|
||||||
++offset;
|
++offset;
|
||||||
}
|
}
|
||||||
assert( (value==0) || ( (value>=cMinValue) && (value<=cMaxValue) ) );
|
assert( (value == 0) || ( (value >= cMinValue) && (value <= cMaxValue) ) );
|
||||||
assert( (offset>=cMinOffset) && (offset<=cMaxOffset) );
|
assert( (offset >= cMinOffset) && (offset <= cMaxOffset) );
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
||||||
@@ -42,15 +44,15 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
|||||||
int offset = static_cast<int>(value >> (64-8));
|
int offset = static_cast<int>(value >> (64-8));
|
||||||
value &= ~(255ull << (64-8));
|
value &= ~(255ull << (64-8));
|
||||||
|
|
||||||
if(value==0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
if(offset!=0)
|
if (offset != 0)
|
||||||
throw std::runtime_error("invalid currency value");
|
throw std::runtime_error("invalid currency value");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset -= 142; // center the range
|
offset -= 142; // center the range
|
||||||
if( (value<cMinValue) || (value>cMaxValue) || (offset<cMinOffset) || (offset>cMaxOffset) )
|
if ( (value < cMinValue) || (value > cMaxValue) || (offset < cMinOffset) || (offset > cMaxOffset) )
|
||||||
throw std::runtime_error("invalid currency value");
|
throw std::runtime_error("invalid currency value");
|
||||||
}
|
}
|
||||||
return new STAmount(name, value, offset);
|
return new STAmount(name, value, offset);
|
||||||
@@ -58,23 +60,25 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
|
|||||||
|
|
||||||
std::string STAmount::getText() const
|
std::string STAmount::getText() const
|
||||||
{
|
{
|
||||||
if(value==0) return "0";
|
if (value == 0) return "0";
|
||||||
if( (offset<-25) || (offset>-5) )
|
if ( (offset < -25) || (offset > -5) )
|
||||||
return boost::lexical_cast<std::string>(value) + "e" + boost::lexical_cast<std::string>(offset);
|
return boost::lexical_cast<std::string>(value) + "e" + boost::lexical_cast<std::string>(offset);
|
||||||
|
|
||||||
std::string val="000000000000000000000000000";
|
std::string val = "000000000000000000000000000";
|
||||||
val+=boost::lexical_cast<std::string>(value);
|
val += boost::lexical_cast<std::string>(value);
|
||||||
val+="00000000000000000000000";
|
val += "00000000000000000000000";
|
||||||
|
|
||||||
std::string pre=val.substr(0, offset+43);
|
std::string pre = val.substr(0, offset+43);
|
||||||
std::string post=val.substr(offset+43);
|
std::string post = val.substr(offset+43);
|
||||||
|
|
||||||
size_t s_pre=pre.find_first_not_of('0');
|
size_t s_pre = pre.find_first_not_of('0');
|
||||||
if(s_pre==std::string::npos) pre="0";
|
if (s_pre == std::string::npos)
|
||||||
else pre=pre.substr(s_pre);
|
pre="0";
|
||||||
|
else
|
||||||
|
pre = pre.substr(s_pre);
|
||||||
|
|
||||||
size_t s_post=post.find_last_not_of('0');
|
size_t s_post = post.find_last_not_of('0');
|
||||||
if(s_post==std::string::npos)
|
if (s_post == std::string::npos)
|
||||||
return pre;
|
return pre;
|
||||||
else
|
else
|
||||||
return pre + "." + post.substr(0, s_post+1);
|
return pre + "." + post.substr(0, s_post+1);
|
||||||
@@ -82,16 +86,16 @@ std::string STAmount::getText() const
|
|||||||
|
|
||||||
void STAmount::add(Serializer& s) const
|
void STAmount::add(Serializer& s) const
|
||||||
{
|
{
|
||||||
if (value==0)
|
if (value == 0)
|
||||||
s.add64(0);
|
s.add64(0);
|
||||||
else
|
else
|
||||||
s.add64(value + (static_cast<uint64>(offset+142) << (64-8)));
|
s.add64(value + (static_cast<uint64>(offset + 142) << (64 - 8)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STAmount::isEquivalent(const SerializedType& t) const
|
bool STAmount::isEquivalent(const SerializedType& t) const
|
||||||
{
|
{
|
||||||
const STAmount* v = dynamic_cast<const STAmount*>(&t);
|
const STAmount* v = dynamic_cast<const STAmount*>(&t);
|
||||||
if(!v) return false;
|
if (!v) return false;
|
||||||
return (value == v->value) && (offset == v->offset);
|
return (value == v->value) && (offset == v->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,33 +111,33 @@ bool STAmount::operator!=(const STAmount& a) const
|
|||||||
|
|
||||||
bool STAmount::operator<(const STAmount& a) const
|
bool STAmount::operator<(const STAmount& a) const
|
||||||
{
|
{
|
||||||
if(value == 0) return false;
|
if (value == 0) return false;
|
||||||
if(offset < a.offset) return true;
|
if (offset < a.offset) return true;
|
||||||
if(a.offset < offset) return false;
|
if (a.offset < offset) return false;
|
||||||
return value < a.value;
|
return value < a.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STAmount::operator>(const STAmount& a) const
|
bool STAmount::operator>(const STAmount& a) const
|
||||||
{
|
{
|
||||||
if(value == 0) return a.value != 0;
|
if (value == 0) return a.value != 0;
|
||||||
if(offset > a.offset) return true;
|
if (offset > a.offset) return true;
|
||||||
if(a.offset > offset) return false;
|
if (a.offset > offset) return false;
|
||||||
return value > a.value;
|
return value > a.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STAmount::operator<=(const STAmount& a) const
|
bool STAmount::operator<=(const STAmount& a) const
|
||||||
{
|
{
|
||||||
if(value == 0) return a.value== 0;
|
if (value == 0) return a.value == 0;
|
||||||
if(offset<a.offset) return true;
|
if (offset < a.offset) return true;
|
||||||
if(a.offset<offset) return false;
|
if (a.offset < offset) return false;
|
||||||
return value <= a.value;
|
return value <= a.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool STAmount::operator>=(const STAmount& a) const
|
bool STAmount::operator>=(const STAmount& a) const
|
||||||
{
|
{
|
||||||
if(value == 0) return true;
|
if (value == 0) return true;
|
||||||
if(offset>a.offset) return true;
|
if (offset > a.offset) return true;
|
||||||
if(a.offset>offset) return false;
|
if (a.offset > offset) return false;
|
||||||
return value >= a.value;
|
return value >= a.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,57 +155,65 @@ STAmount& STAmount::operator-=(const STAmount& a)
|
|||||||
|
|
||||||
STAmount& STAmount::operator=(const STAmount& a)
|
STAmount& STAmount::operator=(const STAmount& a)
|
||||||
{
|
{
|
||||||
value=a.value;
|
value = a.value;
|
||||||
offset=a.offset;
|
offset = a.offset;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount& STAmount::operator=(uint64 v)
|
STAmount& STAmount::operator=(uint64 v)
|
||||||
{
|
{
|
||||||
return *this=STAmount(v, 0);
|
return *this = STAmount(v, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount& STAmount::operator+=(uint64 v)
|
STAmount& STAmount::operator+=(uint64 v)
|
||||||
{
|
{
|
||||||
return *this+=STAmount(v);
|
return *this += STAmount(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount& STAmount::operator-=(uint64 v)
|
STAmount& STAmount::operator-=(uint64 v)
|
||||||
{
|
{
|
||||||
return *this-=STAmount(v);
|
return *this -= STAmount(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount::operator double() const
|
STAmount::operator double() const
|
||||||
{
|
{
|
||||||
if(!value) return 0.0;
|
if (!value)
|
||||||
return (static_cast<double>(value)) * pow(10.0, offset);
|
return 0.0;
|
||||||
|
return static_cast<double>(value) * pow(10.0, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount operator+(STAmount v1, STAmount v2)
|
STAmount operator+(STAmount v1, STAmount v2)
|
||||||
{ // We can check for precision loss here (value%10)!=0
|
{ // We can check for precision loss here (value%10)!=0
|
||||||
|
if (v1.value == 0) return v2;
|
||||||
|
if (v2.value == 0) return v1;
|
||||||
while(v1.offset < v2.offset)
|
while(v1.offset < v2.offset)
|
||||||
{
|
{
|
||||||
v1.value/=10;
|
v1.value /= 10;
|
||||||
v1.offset+=1;
|
++v1.offset;
|
||||||
}
|
}
|
||||||
while(v2.offset < v1.offset)
|
while(v2.offset < v1.offset)
|
||||||
{
|
{
|
||||||
v2.value/=10;
|
v2.value /= 10;
|
||||||
v2.offset+=1;
|
++v2.offset;
|
||||||
}
|
}
|
||||||
// this addition cannot overflow
|
// this addition cannot overflow
|
||||||
return STAmount(v1.name, v1.value + v2.value, v1.offset);
|
return STAmount(v1.name, v1.value + v2.value, v1.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount operator-(STAmount v1, STAmount v2)
|
STAmount operator-(STAmount v1, STAmount v2)
|
||||||
{ // We can check for precision loss here (value%10)!=0
|
{
|
||||||
if(v2.offset > v1.offset) throw std::runtime_error("value underflow");
|
if (v2.value == 0) return v1;
|
||||||
|
if ( (v1.value == 0) || (v2.offset > v1.offset) )
|
||||||
|
throw std::runtime_error("value underflow");
|
||||||
|
|
||||||
while(v1.offset > v2.offset)
|
while(v1.offset > v2.offset)
|
||||||
{
|
{
|
||||||
v2.value/=10;
|
v2.value /= 10;
|
||||||
++v2.offset;
|
++v2.offset;
|
||||||
}
|
}
|
||||||
if(v1.value < v2.value) throw std::runtime_error("value underflow");
|
if (v1.value < v2.value)
|
||||||
|
throw std::runtime_error("value underflow");
|
||||||
|
|
||||||
return STAmount(v1.name, v1.value - v2.value, v1.offset);
|
return STAmount(v1.name, v1.value - v2.value, v1.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,39 +221,41 @@ STAmount operator/(const STAmount& num, const STAmount& den)
|
|||||||
{
|
{
|
||||||
CBigNum numerator, denominator, quotient;
|
CBigNum numerator, denominator, quotient;
|
||||||
|
|
||||||
if(den.value == 0) throw std::runtime_error("illegal offer");
|
if (den.value == 0) throw std::runtime_error("illegal offer");
|
||||||
if(num.value == 0) return STAmount();
|
if (num.value == 0) return STAmount();
|
||||||
|
|
||||||
// Compute (numerator * 10^16) / denominator
|
// Compute (numerator * 10^16) / denominator
|
||||||
if( (BN_add_word(&numerator, num.value) != 1) ||
|
if ((BN_add_word(&numerator, num.value) != 1) ||
|
||||||
(BN_add_word(&denominator, den.value) != 1) ||
|
(BN_add_word(&denominator, den.value) != 1) ||
|
||||||
(BN_mul_word(&numerator, 10000000000000000ull) != 1) ||
|
(BN_mul_word(&numerator, 10000000000000000ull) != 1) ||
|
||||||
(BN_div("ient, NULL, &numerator, &denominator, CAutoBN_CTX()) != 1) )
|
(BN_div("ient, NULL, &numerator, &denominator, CAutoBN_CTX()) != 1))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("internal bn error");
|
throw std::runtime_error("internal bn error");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10^15 <= quotient <= 10^17
|
// 10^15 <= quotient <= 10^17
|
||||||
assert(BN_num_bytes("ient)<=60);
|
assert(BN_num_bytes("ient) <= 60);
|
||||||
|
|
||||||
return STAmount(quotient.getulong(), num.offset - den.offset - 16);
|
return STAmount(quotient.getulong(), num.offset - den.offset - 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount operator*(const STAmount &v1, const STAmount &v2)
|
STAmount operator*(const STAmount &v1, const STAmount &v2)
|
||||||
{
|
{
|
||||||
if( (v1.value == 0) || (v2.value == 0) ) return STAmount();
|
if ( (v1.value == 0) || (v2.value == 0) )
|
||||||
|
return STAmount();
|
||||||
|
|
||||||
// Compute (numerator*10 * denominator*10) / 10^18
|
// Compute (numerator*10 * denominator*10) / 10^18
|
||||||
CBigNum v;
|
CBigNum v;
|
||||||
if( (BN_add_word(&v, (v1.value*10) + 3) != 1) ||
|
if ((BN_add_word(&v, (v1.value*10) + 3) != 1) ||
|
||||||
(BN_mul_word(&v, (v2.value*10) + 3) != 1) ||
|
(BN_mul_word(&v, (v2.value*10) + 3) != 1) ||
|
||||||
(BN_div_word(&v, 1000000000000000000ull) == ((BN_ULONG)-1)) )
|
(BN_div_word(&v, 1000000000000000000ull) == ((BN_ULONG)-1)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("internal bn error");
|
throw std::runtime_error("internal bn error");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10^16 <= product <= 10^18
|
// 10^16 <= product <= 10^18
|
||||||
assert(BN_num_bytes(&v)<=60);
|
assert(BN_num_bytes(&v) <= 60);
|
||||||
|
|
||||||
return STAmount(v.getulong(), v1.offset + v2.offset + 16);
|
return STAmount(v.getulong(), v1.offset + v2.offset + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +272,7 @@ STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
|||||||
// If you pay nothing, you get nothing. Offer is untouched
|
// If you pay nothing, you get nothing. Offer is untouched
|
||||||
if (paid.value == 0) return STAmount();
|
if (paid.value == 0) return STAmount();
|
||||||
|
|
||||||
if( (offerIn.value == 0) || (offerOut.value == 0) )
|
if ( (offerIn.value == 0) || (offerOut.value == 0) )
|
||||||
{ // If the other is invalid or empty, you pay nothing and get nothing and the offer is dead
|
{ // If the other is invalid or empty, you pay nothing and get nothing and the offer is dead
|
||||||
offerIn.zero();
|
offerIn.zero();
|
||||||
offerOut.zero();
|
offerOut.zero();
|
||||||
@@ -266,7 +280,7 @@ STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
|||||||
return STAmount();
|
return STAmount();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(paid >= offerIn)
|
if (paid >= offerIn)
|
||||||
{ // If you pay equal to or more than the offer amount, you get the whole offer and pay its input
|
{ // If you pay equal to or more than the offer amount, you get the whole offer and pay its input
|
||||||
STAmount ret(offerOut);
|
STAmount ret(offerOut);
|
||||||
paid = offerIn;
|
paid = offerIn;
|
||||||
@@ -279,7 +293,7 @@ STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
|||||||
STAmount ret = (paid * offerOut) / offerIn;
|
STAmount ret = (paid * offerOut) / offerIn;
|
||||||
offerOut -= ret;
|
offerOut -= ret;
|
||||||
offerIn -= paid;
|
offerIn -= paid;
|
||||||
if( (offerOut.value == 0) || (offerIn.value == 0) )
|
if ( (offerOut.value == 0) || (offerIn.value == 0) )
|
||||||
{
|
{
|
||||||
offerIn.zero();
|
offerIn.zero();
|
||||||
offerOut.zero();
|
offerOut.zero();
|
||||||
@@ -289,8 +303,8 @@ STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
|
|||||||
|
|
||||||
STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed)
|
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?
|
{ // Someone wants to get (needed) out of the offer, how much should they pay in?
|
||||||
if(offerOut.isZero()) return STAmount();
|
if (offerOut.isZero()) return STAmount();
|
||||||
if(needed >= offerOut) return needed;
|
if (needed >= offerOut) return needed;
|
||||||
STAmount ret = (needed * offerIn) / offerOut;
|
STAmount ret = (needed * offerIn) / offerOut;
|
||||||
return (ret > offerIn) ? offerIn : ret;
|
return (ret > offerIn) ? offerIn : ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user