Add IOUAmount and XRPAmount (RIPD-976):

These numeric types replace the monolithic functionality
found in STAmount. They are not used yet.
This commit is contained in:
Nik Bougalis
2015-07-09 22:50:17 -07:00
committed by Vinnie Falco
parent edc1bc35fd
commit 59431c513a
9 changed files with 741 additions and 2 deletions

View File

@@ -2767,6 +2767,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\IOUAmount.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\Keylet.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
@@ -2887,6 +2891,8 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\InnerObjectFormats.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\IOUAmount.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\Issue.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\JsonFields.h">
@@ -2963,6 +2969,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\IOUAmount.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Issue.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
@@ -2995,6 +3005,10 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\XRPAmount.test.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\tokens.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\TxFlags.h">
@@ -3007,6 +3021,8 @@
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\UintTypes.h">
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\XRPAmount.h">
</ClInclude>
<CustomBuild Include="..\..\src\ripple\proto\ripple.proto">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">protoc --cpp_out=..\..\build\proto --proto_path=%(RelativeDir) %(Identity)</Command>

View File

@@ -3486,6 +3486,9 @@
<ClCompile Include="..\..\src\ripple\protocol\impl\InnerObjectFormats.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\IOUAmount.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\impl\Keylet.cpp">
<Filter>ripple\protocol\impl</Filter>
</ClCompile>
@@ -3582,6 +3585,9 @@
<ClInclude Include="..\..\src\ripple\protocol\InnerObjectFormats.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\IOUAmount.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\Issue.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
@@ -3690,6 +3696,9 @@
<ClCompile Include="..\..\src\ripple\protocol\tests\InnerObjectFormats.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\IOUAmount.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\Issue.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
@@ -3714,6 +3723,9 @@
<ClCompile Include="..\..\src\ripple\protocol\tests\types_test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ripple\protocol\tests\XRPAmount.test.cpp">
<Filter>ripple\protocol\tests</Filter>
</ClCompile>
<ClInclude Include="..\..\src\ripple\protocol\tokens.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
@@ -3732,6 +3744,9 @@
<ClInclude Include="..\..\src\ripple\protocol\UintTypes.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
<ClInclude Include="..\..\src\ripple\protocol\XRPAmount.h">
<Filter>ripple\protocol</Filter>
</ClInclude>
<CustomBuild Include="..\..\src\ripple\proto\ripple.proto">
<Filter>ripple\proto</Filter>
</CustomBuild>

View File

@@ -0,0 +1,142 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_IOUAMOUNT_H_INCLUDED
#define RIPPLE_PROTOCOL_IOUAMOUNT_H_INCLUDED
#include <beast/utility/noexcept.h>
#include <beast/utility/Zero.h>
#include <boost/operators.hpp>
#include <cstdint>
#include <utility>
using beast::zero;
namespace ripple {
/** Floating point representation of amounts with high dynamic range
Amounts are stored as a normalized signed mantissa and an exponent. The
range of the normalized exponent is [-96,80] and the range of the absolute
value of the normalized mantissa is [1000000000000000, 9999999999999999].
Arithmetic operations can throw std::overflow_error during normalization
if the amount exceeds the largest representable amount, but underflows
will silently trunctate to zero.
*/
class IOUAmount
: private boost::totally_ordered<IOUAmount>
, private boost::additive <IOUAmount>
{
private:
std::int64_t mantissa_;
int exponent_;
/** Adjusts the mantissa and exponent to the proper range.
This can throw if the amount cannot be normalized, or is larger than
the largest value that can be represented as an IOU amount. Amounts
that are too small to be represented normalize to 0.
*/
void
normalize ();
public:
IOUAmount () = default;
IOUAmount (IOUAmount const& other) = default;
IOUAmount&operator= (IOUAmount const& other) = default;
IOUAmount (beast::Zero)
{
*this = zero;
}
IOUAmount (std::int64_t mantissa, int exponent)
: mantissa_ (mantissa)
, exponent_ (exponent)
{
normalize ();
}
IOUAmount&
operator= (beast::Zero)
{
// The -100 is used to allow 0 to sort less than small positive values
// which will have a large negative exponent.
mantissa_ = 0;
exponent_ = -100;
return *this;
}
IOUAmount&
operator+= (IOUAmount const& other);
IOUAmount&
operator-= (IOUAmount const& other)
{
*this += -other;
return *this;
}
IOUAmount
operator- () const
{
return { -mantissa_, exponent_ };
}
bool
operator==(IOUAmount const& other) const
{
return exponent_ == other.exponent_ &&
mantissa_ == other.mantissa_;
}
bool
operator<(IOUAmount const& other) const;
/** Returns true if the amount is not zero */
explicit
operator bool() const noexcept
{
return mantissa_ != 0;
}
/** Return the sign of the amount */
int
signum() const noexcept
{
return (mantissa_ < 0) ? -1 : (mantissa_ ? 1 : 0);
}
int
exponent() const noexcept
{
return exponent_;
}
std::int64_t
mantissa() const noexcept
{
return mantissa_;
}
};
}
#endif

View File

@@ -0,0 +1,126 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
#define RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
#include <ripple/protocol/SystemParameters.h>
#include <beast/utility/noexcept.h>
#include <beast/utility/Zero.h>
#include <boost/operators.hpp>
#include <cstdint>
using beast::zero;
namespace ripple {
class XRPAmount
: private boost::totally_ordered <XRPAmount>
, private boost::additive <XRPAmount>
{
private:
std::int64_t value_;
public:
/** @{ */
XRPAmount () = default;
XRPAmount (XRPAmount const& other) = default;
XRPAmount& operator= (XRPAmount const& other) = default;
XRPAmount (beast::Zero)
: value_ (0)
{
}
XRPAmount&
operator= (beast::Zero)
{
value_ = 0;
return *this;
}
XRPAmount (std::int64_t value)
: value_ (value)
{
}
XRPAmount&
operator= (std::int64_t v)
{
value_ = v;
return *this;
}
XRPAmount&
operator+= (XRPAmount const& other)
{
value_ += other.value_;
return *this;
}
XRPAmount&
operator-= (XRPAmount const& other)
{
value_ -= other.value_;
return *this;
}
XRPAmount
operator- () const
{
return { -value_ };
}
bool
operator==(XRPAmount const& other) const
{
return value_ == other.value_;
}
bool
operator<(XRPAmount const& other) const
{
return value_ < other.value_;
}
/** Returns true if the amount is not zero */
explicit
operator bool() const noexcept
{
return value_ != 0;
}
/** Return the sign of the amount */
int
signum() const noexcept
{
return (value_ < 0) ? -1 : (value_ ? 1 : 0);
}
};
/** Returns true if the amount does not exceed the initial XRP in existence. */
inline
bool isLegalAmount (XRPAmount const& amount)
{
return amount <= SYSTEM_CURRENCY_START;
}
}
#endif

View File

@@ -0,0 +1,148 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/IOUAmount.h>
#include <stdexcept>
namespace ripple {
void
IOUAmount::normalize ()
{
/* The range for the exponent when normalized */
static int const minExponent = -96;
static int const maxExponent = 80;
/* The range for the mantissa when normalized */
static std::int64_t const minMantissa = 1000000000000000ull;
static std::int64_t const maxMantissa = 9999999999999999ull;
if (mantissa_ == 0)
{
*this = zero;
return;
}
bool const negative = (mantissa_ < 0);
if (negative)
mantissa_ = -mantissa_;
while ((mantissa_ < minMantissa) && (exponent_ > minExponent))
{
mantissa_ *= 10;
--exponent_;
}
while (mantissa_ > maxMantissa)
{
if (exponent_ >= maxExponent)
throw std::overflow_error ("IOUAmount::normalize");
mantissa_ /= 10;
++exponent_;
}
if ((exponent_ < minExponent) || (mantissa_ < minMantissa))
{
*this = zero;
return;
}
if (exponent_ > maxExponent)
throw std::overflow_error ("value overflow");
if (negative)
mantissa_ = -mantissa_;
}
IOUAmount&
IOUAmount::operator+= (IOUAmount const& other)
{
if (other == zero)
return *this;
if (*this == zero)
{
*this = other;
return *this;
}
auto m = other.mantissa_;
auto e = other.exponent_;
while (exponent_ < e)
{
mantissa_ /= 10;
++exponent_;
}
while (e < exponent_)
{
m /= 10;
++e;
}
// This addition cannot overflow an std::int64_t but we may throw from
// normalize if the result isn't representable.
mantissa_ += m;
if (mantissa_ >= -10 && mantissa_ <= 10)
{
*this = zero;
return *this;
}
normalize ();
return *this;
}
bool
IOUAmount::operator<(IOUAmount const& other) const
{
// If the two amounts have different signs (zero is treated as positive)
// then the comparison is true iff the left is negative.
bool const lneg = mantissa_ < 0;
bool const rneg = other.mantissa_ < 0;
if (lneg != rneg)
return lneg;
// Both have same sign and the left is zero: the right must be
// greater than 0.
if (mantissa_ == 0)
return other.mantissa_ > 0;
// Both have same sign, the right is zero and the left is non-zero.
if (other.mantissa_ == 0)
return false;
// Both have the same sign, compare by exponents:
if (exponent_ > other.exponent_)
return lneg;
if (exponent_ < other.exponent_)
return !lneg;
// If equal exponents, compare mantissas
return mantissa_ < other.mantissa_;
}
}

View File

@@ -18,6 +18,8 @@
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/crypto/CBigNum.h>
@@ -621,7 +623,9 @@ void STAmount::canonicalize ()
if ((mOffset < cMinOffset) || (mValue < cMinValue))
{
mValue = 0;
mOffset = 0;
mIsNegative = false;
mOffset = -100;
return;
}
if (mOffset > cMaxOffset)
@@ -913,7 +917,6 @@ operator- (STAmount const& value)
// Arithmetic
//
//------------------------------------------------------------------------------
STAmount
divide (STAmount const& num, STAmount const& den, Issue const& issue)
{

View File

@@ -0,0 +1,161 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/IOUAmount.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class IOUAmount_test : public beast::unit_test::suite
{
public:
void testZero ()
{
testcase ("zero");
IOUAmount const z (0, 0);
expect (z.mantissa () == 0);
expect (z.exponent () == -100);
expect (!z);
expect (z.signum () == 0);
expect (z == zero);
expect ((z + z) == z);
expect ((z - z) == z);
expect (z == -z);
IOUAmount const zz (zero);
expect (z == zz);
}
void testSigNum ()
{
testcase ("signum");
IOUAmount const neg (-1, 0);
expect (neg.signum () < 0);
IOUAmount const zer (0, 0);
expect (zer.signum () == 0);
IOUAmount const pos (1, 0);
expect (pos.signum () > 0);
}
void testBeastZero ()
{
testcase ("beast::Zero Comparisons");
{
IOUAmount z (zero);
expect (z == zero);
expect (z >= zero);
expect (z <= zero);
unexpected (z != zero);
unexpected (z > zero);
unexpected (z < zero);
}
{
IOUAmount const neg (-2, 0);
expect (neg < zero);
expect (neg <= zero);
expect (neg != zero);
unexpected (neg == zero);
}
{
IOUAmount const pos (2, 0);
expect (pos > zero);
expect (pos >= zero);
expect (pos != zero);
unexpected (pos == zero);
}
}
void testComparisons ()
{
testcase ("IOU Comparisons");
IOUAmount const n (-2, 0);
IOUAmount const z (0, 0);
IOUAmount const p (2, 0);
expect (z == z);
expect (z >= z);
expect (z <= z);
expect (z == -z);
unexpected (z > z);
unexpected (z < z);
unexpected (z != z);
unexpected (z != -z);
expect (n < z);
expect (n <= z);
expect (n != z);
unexpected (n > z);
unexpected (n >= z);
unexpected (n == z);
expect (p > z);
expect (p >= z);
expect (p != z);
unexpected (p < z);
unexpected (p <= z);
unexpected (p == z);
expect (n < p);
expect (n <= p);
expect (n != p);
unexpected (n > p);
unexpected (n >= p);
unexpected (n == p);
expect (p > n);
expect (p >= n);
expect (p != n);
unexpected (p < n);
unexpected (p <= n);
unexpected (p == n);
expect (p > -p);
expect (p >= -p);
expect (p != -p);
expect (n < -n);
expect (n <= -n);
expect (n != -n);
}
//--------------------------------------------------------------------------
void run ()
{
testZero ();
testSigNum ();
testBeastZero ();
testComparisons ();
}
};
BEAST_DEFINE_TESTSUITE(IOUAmount,protocol,ripple);
} // ripple

View File

@@ -0,0 +1,125 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/XRPAmount.h>
#include <beast/unit_test/suite.h>
namespace ripple {
class XRPAmount_test : public beast::unit_test::suite
{
public:
void testSigNum ()
{
testcase ("signum");
for (auto i : { -1, 0, 1})
{
XRPAmount const x(i);
if (i < 0)
expect (x.signum () < 0);
else if (i > 0)
expect (x.signum () > 0);
else
expect (x.signum () == 0);
}
}
void testBeastZero ()
{
testcase ("beast::Zero Comparisons");
for (auto i : { -1, 0, 1})
{
XRPAmount const x (i);
expect ((i == 0) == (x == zero));
expect ((i != 0) == (x != zero));
expect ((i < 0) == (x < zero));
expect ((i > 0) == (x > zero));
expect ((i <= 0) == (x <= zero));
expect ((i >= 0) == (x >= zero));
expect ((0 == i) == (zero == x));
expect ((0 != i) == (zero != x));
expect ((0 < i) == (zero < x));
expect ((0 > i) == (zero > x));
expect ((0 <= i) == (zero <= x));
expect ((0 >= i) == (zero >= x));
}
}
void testComparisons ()
{
testcase ("XRP Comparisons");
for (auto i : { -1, 0, 1})
{
XRPAmount const x (i);
for (auto j : { -1, 0, 1})
{
XRPAmount const y (j);
expect ((i == j) == (x == y));
expect ((i != j) == (x != y));
expect ((i < j) == (x < y));
expect ((i > j) == (x > y));
expect ((i <= j) == (x <= y));
expect ((i >= j) == (x >= y));
}
}
}
void testAddSub ()
{
testcase ("Addition & Subtraction");
for (auto i : { -1, 0, 1})
{
XRPAmount const x (i);
for (auto j : { -1, 0, 1})
{
XRPAmount const y (j);
expect (XRPAmount(i + j) == (x + y));
expect (XRPAmount(i - j) == (x - y));
expect ((x + y) == (y + x)); // addition is commutative
}
}
}
//--------------------------------------------------------------------------
void run ()
{
testSigNum ();
testBeastZero ();
testComparisons ();
testAddSub ();
}
};
BEAST_DEFINE_TESTSUITE(XRPAmount,protocol,ripple);
} // ripple

View File

@@ -56,10 +56,12 @@
#include <ripple/protocol/impl/STValidation.cpp>
#include <ripple/protocol/impl/STVar.cpp>
#include <ripple/protocol/impl/STVector256.cpp>
#include <ripple/protocol/impl/IOUAmount.cpp>
#include <ripple/protocol/tests/BuildInfo.test.cpp>
#include <ripple/protocol/tests/InnerObjectFormats.test.cpp>
#include <ripple/protocol/tests/IOUAmount.test.cpp>
#include <ripple/protocol/tests/Issue.test.cpp>
#include <ripple/protocol/tests/PublicKey_test.cpp>
#include <ripple/protocol/tests/Quality.test.cpp>
@@ -68,6 +70,7 @@
#include <ripple/protocol/tests/STObject.test.cpp>
#include <ripple/protocol/tests/STTx.test.cpp>
#include <ripple/protocol/tests/types_test.cpp>
#include <ripple/protocol/tests/XRPAmount.test.cpp>
#if DOXYGEN
#include <ripple/protocol/README.md>