diff --git a/src/Amount.cpp b/src/Amount.cpp index 752a0f3bf6..3cc30d7e0c 100644 --- a/src/Amount.cpp +++ b/src/Amount.cpp @@ -14,11 +14,13 @@ void STAmount::canonicalize() } while(valuecMaxValue) { // Here we can make it throw on precision loss if we wish: ((value%10)!=0) + if(offset>=cMaxOffset) throw std::runtime_error("value underflow"); value/=10; offset+=1; } @@ -64,6 +66,110 @@ bool STAmount::isEquivalent(const SerializedType& t) const return (value==v->value) && (offset==v->offset); } +bool STAmount::operator==(const STAmount& a) const +{ + return (offset==a.offset) && (value==a.value); +} + +bool STAmount::operator!=(const STAmount& a) const +{ + return (offset!=a.offset) || (value!=a.value); +} + +bool STAmount::operator<(const STAmount& a) const +{ + if(offset(const STAmount& a) const +{ + if(offset>a.offset) return true; + if(a.offset>offset) return false; + return value > a.value; +} + +bool STAmount::operator<=(const STAmount& a) const +{ + if(offset=(const STAmount& a) const +{ + if(offset>a.offset) return true; + if(a.offset>offset) return false; + return value >= a.value; +} + +STAmount& STAmount::operator+=(const STAmount& a) +{ + *this = *this + a; + return *this; +} + +STAmount& STAmount::operator-=(const STAmount& a) +{ + *this = *this - a; + return *this; +} + +STAmount& STAmount::operator=(const STAmount& a) +{ + value=a.value; + offset=a.offset; + return *this; +} + +STAmount& STAmount::operator=(uint64 v) +{ + return *this=STAmount(v, 0); +} + +STAmount& STAmount::operator+=(uint64 v) +{ + return *this+=STAmount(v); +} + +STAmount& STAmount::operator-=(uint64 v) +{ + return *this-=STAmount(v); +} + +STAmount operator+(STAmount v1, STAmount v2) +{ // We can check for precision loss here (value%10)!=0 + while(v1.offset < v2.offset) + { + v1.value/=10; + v1.offset+=1; + } + while(v2.offset < v1.offset) + { + v2.value/=10; + v2.offset+=1; + } + // this addition cannot overflow + return STAmount(v1.name, v1.value + v2.value, v1.offset); +} + +STAmount operator-(STAmount v1, STAmount v2) +{ // We can check for precision loss here (value%10)!=0 + while(v1.offset < v2.offset) + { + v1.value/=10; + v1.offset+=1; + } + while(v2.offset < v1.offset) + { + v2.value/=10; + v2.offset+=1; + } + if(v1.value < v2.value) throw std::runtime_error("value overflow"); + return STAmount(v1.name, v1.value - v2.value, v1.offset); +} + STAmount::operator double() const { if(!value) return 0.0; diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index b65265b9f7..1a4958d41a 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -30,6 +30,7 @@ public: SerializedType() : name(NULL) { ; } SerializedType(const char *n) : name(n) { ; } + SerializedType(const SerializedType& n) : name(n.name) { ; } virtual ~SerializedType() { ; } void setName(const char *n) { name=n; } @@ -170,7 +171,7 @@ class STAmount : public SerializedType // Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive protected: - int offset; // These variables *always* hold canonical values + int offset; // These variables *always* hold canonical values on entry/exit uint64 value; void canonicalize(); @@ -183,6 +184,7 @@ public: { canonicalize(); } // (1,0)=$1 (1,-2)=$.01 (100,0)=(10000,-2)=$.01 STAmount(const char *n, uint64 v=0, int off=1) : SerializedType(n), offset(off), value(v) { canonicalize(); } + STAmount(const STAmount& a) : SerializedType(a), offset(a.offset), value(a.value) { ; } static STAmount* construct(SerializerIterator&, const char *name=NULL); int getLength() const { return 8; } @@ -212,9 +214,17 @@ public: operator double() const; - friend STAmount operator+(const STAmount& v1, const STAmount& v2); - friend STAmount operator-(const STAmount& v1, const STAmount& v2); - friend STAmount operator/(const STAmount& v1, const STAmount& v2); + friend STAmount operator+(STAmount v1, STAmount v2); + friend STAmount operator-(STAmount v1, STAmount v2); + + // Someone is offering X for Y, what is the rate? + friend STAmount getRate(const STAmount& offerIn, const STAmount& offerOut); + + // Someone is offering X for Y, I pay Z, how much do I get? + friend STAmount getClaimed(const STAmount& offerIn, const STAmount& offerOut, const STAmount& paid); + + // Someone is offering X for Y, I need Z, how much fo I pay + friend STAmount getNeeded(const STAmount& offerIn, const STAmount& offerOut, const STAmount& needed); }; class STHash128 : public SerializedType