rippled
Loading...
Searching...
No Matches
IOUAmount_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/beast/unit_test.h>
21#include <xrpl/protocol/IOUAmount.h>
22
23namespace ripple {
24
26{
27public:
28 void
30 {
31 testcase("zero");
32
33 IOUAmount const z(0, 0);
34
35 BEAST_EXPECT(z.mantissa() == 0);
36 BEAST_EXPECT(z.exponent() == -100);
37 BEAST_EXPECT(!z);
38 BEAST_EXPECT(z.signum() == 0);
39 BEAST_EXPECT(z == beast::zero);
40
41 BEAST_EXPECT((z + z) == z);
42 BEAST_EXPECT((z - z) == z);
43 BEAST_EXPECT(z == -z);
44
45 IOUAmount const zz(beast::zero);
46 BEAST_EXPECT(z == zz);
47
48 // https://github.com/XRPLF/rippled/issues/5170
49 IOUAmount const zzz{};
50 BEAST_EXPECT(zzz == beast::zero);
51 // BEAST_EXPECT(zzz == zz);
52 }
53
54 void
56 {
57 testcase("signum");
58
59 IOUAmount const neg(-1, 0);
60 BEAST_EXPECT(neg.signum() < 0);
61
62 IOUAmount const zer(0, 0);
63 BEAST_EXPECT(zer.signum() == 0);
64
65 IOUAmount const pos(1, 0);
66 BEAST_EXPECT(pos.signum() > 0);
67 }
68
69 void
71 {
72 testcase("beast::Zero Comparisons");
73
74 using beast::zero;
75
76 {
77 IOUAmount z(zero);
78 BEAST_EXPECT(z == zero);
79 BEAST_EXPECT(z >= zero);
80 BEAST_EXPECT(z <= zero);
81 unexpected(z != zero);
82 unexpected(z > zero);
83 unexpected(z < zero);
84 }
85
86 {
87 IOUAmount const neg(-2, 0);
88 BEAST_EXPECT(neg < zero);
89 BEAST_EXPECT(neg <= zero);
90 BEAST_EXPECT(neg != zero);
91 unexpected(neg == zero);
92 }
93
94 {
95 IOUAmount const pos(2, 0);
96 BEAST_EXPECT(pos > zero);
97 BEAST_EXPECT(pos >= zero);
98 BEAST_EXPECT(pos != zero);
99 unexpected(pos == zero);
100 }
101 }
102
103 void
105 {
106 testcase("IOU Comparisons");
107
108 IOUAmount const n(-2, 0);
109 IOUAmount const z(0, 0);
110 IOUAmount const p(2, 0);
111
112 BEAST_EXPECT(z == z);
113 BEAST_EXPECT(z >= z);
114 BEAST_EXPECT(z <= z);
115 BEAST_EXPECT(z == -z);
116 unexpected(z > z);
117 unexpected(z < z);
118 unexpected(z != z);
119 unexpected(z != -z);
120
121 BEAST_EXPECT(n < z);
122 BEAST_EXPECT(n <= z);
123 BEAST_EXPECT(n != z);
124 unexpected(n > z);
125 unexpected(n >= z);
126 unexpected(n == z);
127
128 BEAST_EXPECT(p > z);
129 BEAST_EXPECT(p >= z);
130 BEAST_EXPECT(p != z);
131 unexpected(p < z);
132 unexpected(p <= z);
133 unexpected(p == z);
134
135 BEAST_EXPECT(n < p);
136 BEAST_EXPECT(n <= p);
137 BEAST_EXPECT(n != p);
138 unexpected(n > p);
139 unexpected(n >= p);
140 unexpected(n == p);
141
142 BEAST_EXPECT(p > n);
143 BEAST_EXPECT(p >= n);
144 BEAST_EXPECT(p != n);
145 unexpected(p < n);
146 unexpected(p <= n);
147 unexpected(p == n);
148
149 BEAST_EXPECT(p > -p);
150 BEAST_EXPECT(p >= -p);
151 BEAST_EXPECT(p != -p);
152
153 BEAST_EXPECT(n < -n);
154 BEAST_EXPECT(n <= -n);
155 BEAST_EXPECT(n != -n);
156 }
157
158 void
160 {
161 testcase("IOU strings");
162
163 BEAST_EXPECT(to_string(IOUAmount(-2, 0)) == "-2");
164 BEAST_EXPECT(to_string(IOUAmount(0, 0)) == "0");
165 BEAST_EXPECT(to_string(IOUAmount(2, 0)) == "2");
166 BEAST_EXPECT(to_string(IOUAmount(25, -3)) == "0.025");
167 BEAST_EXPECT(to_string(IOUAmount(-25, -3)) == "-0.025");
168 BEAST_EXPECT(to_string(IOUAmount(25, 1)) == "250");
169 BEAST_EXPECT(to_string(IOUAmount(-25, 1)) == "-250");
170 BEAST_EXPECT(to_string(IOUAmount(2, 20)) == "2000000000000000e5");
171 BEAST_EXPECT(to_string(IOUAmount(-2, -20)) == "-2000000000000000e-35");
172 }
173
174 void
176 {
177 testcase("mulRatio");
178
179 /* The range for the mantissa when normalized */
180 constexpr std::int64_t minMantissa = 1000000000000000ull;
181 constexpr std::int64_t maxMantissa = 9999999999999999ull;
182 // log(2,maxMantissa) ~ 53.15
183 /* The range for the exponent when normalized */
184 constexpr int minExponent = -96;
185 constexpr int maxExponent = 80;
186 constexpr auto maxUInt = std::numeric_limits<std::uint32_t>::max();
187
188 {
189 // multiply by a number that would overflow the mantissa, then
190 // divide by the same number, and check we didn't lose any value
191 IOUAmount bigMan(maxMantissa, 0);
192 BEAST_EXPECT(bigMan == mulRatio(bigMan, maxUInt, maxUInt, true));
193 // rounding mode shouldn't matter as the result is exact
194 BEAST_EXPECT(bigMan == mulRatio(bigMan, maxUInt, maxUInt, false));
195 }
196 {
197 // Similar test as above, but for negative values
198 IOUAmount bigMan(-maxMantissa, 0);
199 BEAST_EXPECT(bigMan == mulRatio(bigMan, maxUInt, maxUInt, true));
200 // rounding mode shouldn't matter as the result is exact
201 BEAST_EXPECT(bigMan == mulRatio(bigMan, maxUInt, maxUInt, false));
202 }
203
204 {
205 // small amounts
207 // Round up should give the smallest allowable number
208 BEAST_EXPECT(tiny == mulRatio(tiny, 1, maxUInt, true));
209 BEAST_EXPECT(tiny == mulRatio(tiny, maxUInt - 1, maxUInt, true));
210 // rounding down should be zero
211 BEAST_EXPECT(beast::zero == mulRatio(tiny, 1, maxUInt, false));
212 BEAST_EXPECT(
213 beast::zero == mulRatio(tiny, maxUInt - 1, maxUInt, false));
214
215 // tiny negative numbers
217 // Round up should give zero
218 BEAST_EXPECT(beast::zero == mulRatio(tinyNeg, 1, maxUInt, true));
219 BEAST_EXPECT(
220 beast::zero == mulRatio(tinyNeg, maxUInt - 1, maxUInt, true));
221 // rounding down should be tiny
222 BEAST_EXPECT(tinyNeg == mulRatio(tinyNeg, 1, maxUInt, false));
223 BEAST_EXPECT(
224 tinyNeg == mulRatio(tinyNeg, maxUInt - 1, maxUInt, false));
225 }
226
227 { // rounding
228 {
229 IOUAmount one(1, 0);
230 auto const rup = mulRatio(one, maxUInt - 1, maxUInt, true);
231 auto const rdown = mulRatio(one, maxUInt - 1, maxUInt, false);
232 BEAST_EXPECT(rup.mantissa() - rdown.mantissa() == 1);
233 }
234 {
236 auto const rup = mulRatio(big, maxUInt - 1, maxUInt, true);
237 auto const rdown = mulRatio(big, maxUInt - 1, maxUInt, false);
238 BEAST_EXPECT(rup.mantissa() - rdown.mantissa() == 1);
239 }
240
241 {
242 IOUAmount negOne(-1, 0);
243 auto const rup = mulRatio(negOne, maxUInt - 1, maxUInt, true);
244 auto const rdown =
245 mulRatio(negOne, maxUInt - 1, maxUInt, false);
246 BEAST_EXPECT(rup.mantissa() - rdown.mantissa() == 1);
247 }
248 }
249
250 {
251 // division by zero
252 IOUAmount one(1, 0);
253 except([&] { mulRatio(one, 1, 0, true); });
254 }
255
256 {
257 // overflow
259 except([&] { mulRatio(big, 2, 0, true); });
260 }
261 } // namespace ripple
262
263 //--------------------------------------------------------------------------
264
265 void
266 run() override
267 {
268 testZero();
269 testSigNum();
272 testToString();
273 testMulRatio();
274 }
275};
276
277BEAST_DEFINE_TESTSUITE(IOUAmount, protocol, ripple);
278
279} // namespace ripple
A testsuite class.
Definition: suite.h:55
bool unexpected(Condition shouldBeFalse, String const &reason)
Definition: suite.h:499
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:155
bool except(F &&f, String const &reason)
Definition: suite.h:448
void run() override
Runs the suite.
Floating point representation of amounts with high dynamic range.
Definition: IOUAmount.h:46
int exponent() const noexcept
Definition: IOUAmount.h:172
int signum() const noexcept
Return the sign of the amount.
Definition: IOUAmount.h:166
std::int64_t mantissa() const noexcept
Definition: IOUAmount.h:178
T max(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
constexpr Number one
Definition: Number.cpp:175
static int constexpr maxExponent
Definition: IOUAmount.cpp:66
static int constexpr minExponent
Definition: IOUAmount.cpp:65
static std::int64_t constexpr maxMantissa
Definition: IOUAmount.cpp:63
static std::int64_t constexpr minMantissa
Definition: IOUAmount.cpp:62
IOUAmount mulRatio(IOUAmount const &amt, std::uint32_t num, std::uint32_t den, bool roundUp)
Definition: IOUAmount.cpp:190
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630