rippled
Number_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2022 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 <ripple/basics/IOUAmount.h>
21 #include <ripple/basics/Number.h>
22 #include <ripple/beast/unit_test.h>
23 #include <ripple/protocol/STAmount.h>
24 #include <sstream>
25 #include <tuple>
26 
27 namespace ripple {
28 
29 class Number_test : public beast::unit_test::suite
30 {
31 public:
32  void
34  {
35  testcase("zero");
36 
37  Number const z{0, 0};
38 
39  BEAST_EXPECT(z.mantissa() == 0);
40  BEAST_EXPECT(z.exponent() == Number{}.exponent());
41 
42  BEAST_EXPECT((z + z) == z);
43  BEAST_EXPECT((z - z) == z);
44  BEAST_EXPECT(z == -z);
45  }
46 
47  void
49  {
50  testcase("test_limits");
51  bool caught = false;
52  try
53  {
54  Number x{10'000'000'000'000'000, 32768};
55  }
56  catch (std::overflow_error const&)
57  {
58  caught = true;
59  }
60  BEAST_EXPECT(caught);
61  Number x{10'000'000'000'000'000, 32767};
62  BEAST_EXPECT((x == Number{1'000'000'000'000'000, 32768}));
63  Number z{1'000'000'000'000'000, -32769};
64  BEAST_EXPECT(z == Number{});
65  Number y{1'000'000'000'000'001'500, 32000};
66  BEAST_EXPECT((y == Number{1'000'000'000'000'002, 32003}));
67  Number m{std::numeric_limits<std::int64_t>::min()};
68  BEAST_EXPECT((m == Number{-9'223'372'036'854'776, 3}));
70  BEAST_EXPECT((M == Number{9'223'372'036'854'776, 3}));
71  caught = false;
72  try
73  {
74  Number q{99'999'999'999'999'999, 32767};
75  }
76  catch (std::overflow_error const&)
77  {
78  caught = true;
79  }
80  BEAST_EXPECT(caught);
81  }
82 
83  void
85  {
86  testcase("test_add");
88  Case c[]{
89  {Number{1'000'000'000'000'000, -15},
90  Number{6'555'555'555'555'555, -29},
91  Number{1'000'000'000'000'066, -15}},
92  {Number{-1'000'000'000'000'000, -15},
93  Number{-6'555'555'555'555'555, -29},
94  Number{-1'000'000'000'000'066, -15}},
95  {Number{-1'000'000'000'000'000, -15},
96  Number{6'555'555'555'555'555, -29},
97  Number{-9'999'999'999'999'344, -16}},
98  {Number{-6'555'555'555'555'555, -29},
99  Number{1'000'000'000'000'000, -15},
100  Number{9'999'999'999'999'344, -16}},
101  {Number{}, Number{5}, Number{5}},
102  {Number{5'555'555'555'555'555, -32768},
103  Number{-5'555'555'555'555'554, -32768},
104  Number{0}},
105  {Number{-9'999'999'999'999'999, -31},
106  Number{1'000'000'000'000'000, -15},
107  Number{9'999'999'999'999'990, -16}}};
108  for (auto const& [x, y, z] : c)
109  BEAST_EXPECT(x + y == z);
110  bool caught = false;
111  try
112  {
113  Number{9'999'999'999'999'999, 32768} +
114  Number{5'000'000'000'000'000, 32767};
115  }
116  catch (std::overflow_error const&)
117  {
118  caught = true;
119  }
120  BEAST_EXPECT(caught);
121  }
122 
123  void
124  test_sub()
125  {
126  testcase("test_sub");
127  using Case = std::tuple<Number, Number, Number>;
128  Case c[]{
129  {Number{1'000'000'000'000'000, -15},
130  Number{6'555'555'555'555'555, -29},
131  Number{9'999'999'999'999'344, -16}},
132  {Number{6'555'555'555'555'555, -29},
133  Number{1'000'000'000'000'000, -15},
134  Number{-9'999'999'999'999'344, -16}},
135  {Number{1'000'000'000'000'000, -15},
136  Number{1'000'000'000'000'000, -15},
137  Number{0}},
138  {Number{1'000'000'000'000'000, -15},
139  Number{1'000'000'000'000'001, -15},
140  Number{-1'000'000'000'000'000, -30}},
141  {Number{1'000'000'000'000'001, -15},
142  Number{1'000'000'000'000'000, -15},
143  Number{1'000'000'000'000'000, -30}}};
144  for (auto const& [x, y, z] : c)
145  BEAST_EXPECT(x - y == z);
146  }
147 
148  void
149  test_mul()
150  {
151  testcase("test_mul");
152  using Case = std::tuple<Number, Number, Number>;
153  saveNumberRoundMode save{Number::setround(Number::to_nearest)};
154  {
155  Case c[]{
156  {Number{7}, Number{8}, Number{56}},
157  {Number{1414213562373095, -15},
158  Number{1414213562373095, -15},
159  Number{2000000000000000, -15}},
160  {Number{-1414213562373095, -15},
161  Number{1414213562373095, -15},
162  Number{-2000000000000000, -15}},
163  {Number{-1414213562373095, -15},
164  Number{-1414213562373095, -15},
165  Number{2000000000000000, -15}},
166  {Number{3214285714285706, -15},
167  Number{3111111111111119, -15},
168  Number{1000000000000000, -14}},
169  {Number{1000000000000000, -32768},
170  Number{1000000000000000, -32768},
171  Number{0}}};
172  for (auto const& [x, y, z] : c)
173  BEAST_EXPECT(x * y == z);
174  }
175  Number::setround(Number::towards_zero);
176  {
177  Case c[]{
178  {Number{7}, Number{8}, Number{56}},
179  {Number{1414213562373095, -15},
180  Number{1414213562373095, -15},
181  Number{1999999999999999, -15}},
182  {Number{-1414213562373095, -15},
183  Number{1414213562373095, -15},
184  Number{-1999999999999999, -15}},
185  {Number{-1414213562373095, -15},
186  Number{-1414213562373095, -15},
187  Number{1999999999999999, -15}},
188  {Number{3214285714285706, -15},
189  Number{3111111111111119, -15},
190  Number{9999999999999999, -15}},
191  {Number{1000000000000000, -32768},
192  Number{1000000000000000, -32768},
193  Number{0}}};
194  for (auto const& [x, y, z] : c)
195  BEAST_EXPECT(x * y == z);
196  }
197  Number::setround(Number::downward);
198  {
199  Case c[]{
200  {Number{7}, Number{8}, Number{56}},
201  {Number{1414213562373095, -15},
202  Number{1414213562373095, -15},
203  Number{1999999999999999, -15}},
204  {Number{-1414213562373095, -15},
205  Number{1414213562373095, -15},
206  Number{-2000000000000000, -15}},
207  {Number{-1414213562373095, -15},
208  Number{-1414213562373095, -15},
209  Number{1999999999999999, -15}},
210  {Number{3214285714285706, -15},
211  Number{3111111111111119, -15},
212  Number{9999999999999999, -15}},
213  {Number{1000000000000000, -32768},
214  Number{1000000000000000, -32768},
215  Number{0}}};
216  for (auto const& [x, y, z] : c)
217  BEAST_EXPECT(x * y == z);
218  }
219  Number::setround(Number::upward);
220  {
221  Case c[]{
222  {Number{7}, Number{8}, Number{56}},
223  {Number{1414213562373095, -15},
224  Number{1414213562373095, -15},
225  Number{2000000000000000, -15}},
226  {Number{-1414213562373095, -15},
227  Number{1414213562373095, -15},
228  Number{-1999999999999999, -15}},
229  {Number{-1414213562373095, -15},
230  Number{-1414213562373095, -15},
231  Number{2000000000000000, -15}},
232  {Number{3214285714285706, -15},
233  Number{3111111111111119, -15},
234  Number{1000000000000000, -14}},
235  {Number{1000000000000000, -32768},
236  Number{1000000000000000, -32768},
237  Number{0}}};
238  for (auto const& [x, y, z] : c)
239  BEAST_EXPECT(x * y == z);
240  }
241  bool caught = false;
242  try
243  {
244  Number{9'999'999'999'999'999, 32768} *
245  Number{5'000'000'000'000'000, 32767};
246  }
247  catch (std::overflow_error const&)
248  {
249  caught = true;
250  }
251  BEAST_EXPECT(caught);
252  }
253 
254  void
255  test_div()
256  {
257  testcase("test_div");
258  using Case = std::tuple<Number, Number, Number>;
259  saveNumberRoundMode save{Number::setround(Number::to_nearest)};
260  {
261  Case c[]{
262  {Number{1}, Number{2}, Number{5, -1}},
263  {Number{1}, Number{10}, Number{1, -1}},
264  {Number{1}, Number{-10}, Number{-1, -1}},
265  {Number{0}, Number{100}, Number{0}},
266  {Number{1414213562373095, -10},
267  Number{1414213562373095, -10},
268  Number{1}},
269  {Number{9'999'999'999'999'999},
270  Number{1'000'000'000'000'000},
271  Number{9'999'999'999'999'999, -15}},
272  {Number{2}, Number{3}, Number{6'666'666'666'666'667, -16}},
273  {Number{-2}, Number{3}, Number{-6'666'666'666'666'667, -16}}};
274  for (auto const& [x, y, z] : c)
275  BEAST_EXPECT(x / y == z);
276  }
278  {
279  Case c[]{
280  {Number{1}, Number{2}, Number{5, -1}},
281  {Number{1}, Number{10}, Number{1, -1}},
282  {Number{1}, Number{-10}, Number{-1, -1}},
283  {Number{0}, Number{100}, Number{0}},
284  {Number{1414213562373095, -10},
285  Number{1414213562373095, -10},
286  Number{1}},
287  {Number{9'999'999'999'999'999},
288  Number{1'000'000'000'000'000},
289  Number{9'999'999'999'999'999, -15}},
290  {Number{2}, Number{3}, Number{6'666'666'666'666'666, -16}},
291  {Number{-2}, Number{3}, Number{-6'666'666'666'666'666, -16}}};
292  for (auto const& [x, y, z] : c)
293  BEAST_EXPECT(x / y == z);
294  }
295  Number::setround(Number::downward);
296  {
297  Case c[]{
298  {Number{1}, Number{2}, Number{5, -1}},
299  {Number{1}, Number{10}, Number{1, -1}},
300  {Number{1}, Number{-10}, Number{-1, -1}},
301  {Number{0}, Number{100}, Number{0}},
302  {Number{1414213562373095, -10},
303  Number{1414213562373095, -10},
304  Number{1}},
305  {Number{9'999'999'999'999'999},
306  Number{1'000'000'000'000'000},
307  Number{9'999'999'999'999'999, -15}},
308  {Number{2}, Number{3}, Number{6'666'666'666'666'666, -16}},
309  {Number{-2}, Number{3}, Number{-6'666'666'666'666'667, -16}}};
310  for (auto const& [x, y, z] : c)
311  BEAST_EXPECT(x / y == z);
312  }
314  {
315  Case c[]{
316  {Number{1}, Number{2}, Number{5, -1}},
317  {Number{1}, Number{10}, Number{1, -1}},
318  {Number{1}, Number{-10}, Number{-1, -1}},
319  {Number{0}, Number{100}, Number{0}},
320  {Number{1414213562373095, -10},
321  Number{1414213562373095, -10},
322  Number{1}},
323  {Number{9'999'999'999'999'999},
324  Number{1'000'000'000'000'000},
325  Number{9'999'999'999'999'999, -15}},
326  {Number{2}, Number{3}, Number{6'666'666'666'666'667, -16}},
327  {Number{-2}, Number{3}, Number{-6'666'666'666'666'666, -16}}};
328  for (auto const& [x, y, z] : c)
329  BEAST_EXPECT(x / y == z);
330  }
331  bool caught = false;
332  try
333  {
334  Number{1000000000000000, -15} / Number{0};
335  }
336  catch (std::overflow_error const&)
337  {
338  caught = true;
339  }
340  BEAST_EXPECT(caught);
341  }
342 
343  void
344  test_root()
345  {
346  testcase("test_root");
347  using Case = std::tuple<Number, unsigned, Number>;
348  Case c[]{
349  {Number{2}, 2, Number{1414213562373095, -15}},
350  {Number{2'000'000}, 2, Number{1414213562373095, -12}},
351  {Number{2, -30}, 2, Number{1414213562373095, -30}},
352  {Number{-27}, 3, Number{-3}},
353  {Number{1}, 5, Number{1}},
354  {Number{-1}, 0, Number{1}},
355  {Number{5, -1}, 0, Number{0}},
356  {Number{0}, 5, Number{0}},
357  {Number{5625, -4}, 2, Number{75, -2}}};
358  for (auto const& [x, y, z] : c)
359  BEAST_EXPECT((root(x, y) == z));
360  bool caught = false;
361  try
362  {
363  (void)root(Number{-2}, 0);
364  }
365  catch (std::overflow_error const&)
366  {
367  caught = true;
368  }
369  BEAST_EXPECT(caught);
370  caught = false;
371  try
372  {
373  (void)root(Number{-2}, 4);
374  }
375  catch (std::overflow_error const&)
376  {
377  caught = true;
378  }
379  BEAST_EXPECT(caught);
380  }
381 
382  void
383  test_power1()
384  {
385  testcase("test_power1");
386  using Case = std::tuple<Number, unsigned, Number>;
387  Case c[]{
388  {Number{64}, 0, Number{1}},
389  {Number{64}, 1, Number{64}},
390  {Number{64}, 2, Number{4096}},
391  {Number{-64}, 2, Number{4096}},
392  {Number{64}, 3, Number{262144}},
393  {Number{-64}, 3, Number{-262144}}};
394  for (auto const& [x, y, z] : c)
395  BEAST_EXPECT((power(x, y) == z));
396  }
397 
398  void
399  test_power2()
400  {
401  testcase("test_power2");
402  using Case = std::tuple<Number, unsigned, unsigned, Number>;
403  Case c[]{
404  {Number{1}, 3, 7, Number{1}},
405  {Number{-1}, 1, 0, Number{1}},
406  {Number{-1, -1}, 1, 0, Number{0}},
407  {Number{16}, 0, 5, Number{1}},
408  {Number{34}, 3, 3, Number{34}},
409  {Number{4}, 3, 2, Number{8}}};
410  for (auto const& [x, n, d, z] : c)
411  BEAST_EXPECT((power(x, n, d) == z));
412  bool caught = false;
413  try
414  {
415  (void)power(Number{7}, 0, 0);
416  }
417  catch (std::overflow_error const&)
418  {
419  caught = true;
420  }
421  BEAST_EXPECT(caught);
422  caught = false;
423  try
424  {
425  (void)power(Number{7}, 1, 0);
426  }
427  catch (std::overflow_error const&)
428  {
429  caught = true;
430  }
431  BEAST_EXPECT(caught);
432  caught = false;
433  try
434  {
435  (void)power(Number{-1, -1}, 3, 2);
436  }
437  catch (std::overflow_error const&)
438  {
439  caught = true;
440  }
441  BEAST_EXPECT(caught);
442  }
443 
444  void
445  testConversions()
446  {
447  testcase("testConversions");
448 
449  IOUAmount x{5, 6};
450  Number y = x;
451  BEAST_EXPECT((y == Number{5, 6}));
452  IOUAmount z{y};
453  BEAST_EXPECT(x == z);
454  XRPAmount xrp{500};
455  STAmount st = xrp;
456  Number n = st;
457  BEAST_EXPECT(XRPAmount{n} == xrp);
458  IOUAmount x0{0, 0};
459  Number y0 = x0;
460  BEAST_EXPECT((y0 == Number{0}));
461  IOUAmount z0{y0};
462  BEAST_EXPECT(x0 == z0);
463  XRPAmount xrp0{0};
464  Number n0 = xrp0;
465  BEAST_EXPECT(n0 == Number{0});
466  XRPAmount xrp1{n0};
467  BEAST_EXPECT(xrp1 == xrp0);
468  }
469 
470  void
471  test_to_integer()
472  {
473  testcase("test_to_integer");
474  using Case = std::tuple<Number, std::int64_t>;
475  saveNumberRoundMode save{Number::setround(Number::to_nearest)};
476  {
477  Case c[]{
478  {Number{0}, 0},
479  {Number{1}, 1},
480  {Number{2}, 2},
481  {Number{3}, 3},
482  {Number{-1}, -1},
483  {Number{-2}, -2},
484  {Number{-3}, -3},
485  {Number{10}, 10},
486  {Number{99}, 99},
487  {Number{1155}, 1155},
488  {Number{9'999'999'999'999'999, 0}, 9'999'999'999'999'999},
489  {Number{9'999'999'999'999'999, 1}, 99'999'999'999'999'990},
490  {Number{9'999'999'999'999'999, 2}, 999'999'999'999'999'900},
491  {Number{-9'999'999'999'999'999, 2}, -999'999'999'999'999'900},
492  {Number{15, -1}, 2},
493  {Number{14, -1}, 1},
494  {Number{16, -1}, 2},
495  {Number{25, -1}, 2},
496  {Number{6, -1}, 1},
497  {Number{5, -1}, 0},
498  {Number{4, -1}, 0},
499  {Number{-15, -1}, -2},
500  {Number{-14, -1}, -1},
501  {Number{-16, -1}, -2},
502  {Number{-25, -1}, -2},
503  {Number{-6, -1}, -1},
504  {Number{-5, -1}, 0},
505  {Number{-4, -1}, 0}};
506  for (auto const& [x, y] : c)
507  {
508  auto j = static_cast<std::int64_t>(x);
509  BEAST_EXPECT(j == y);
510  }
511  }
512  auto prev_mode = Number::setround(Number::towards_zero);
513  BEAST_EXPECT(prev_mode == Number::to_nearest);
514  {
515  Case c[]{
516  {Number{0}, 0},
517  {Number{1}, 1},
518  {Number{2}, 2},
519  {Number{3}, 3},
520  {Number{-1}, -1},
521  {Number{-2}, -2},
522  {Number{-3}, -3},
523  {Number{10}, 10},
524  {Number{99}, 99},
525  {Number{1155}, 1155},
526  {Number{9'999'999'999'999'999, 0}, 9'999'999'999'999'999},
527  {Number{9'999'999'999'999'999, 1}, 99'999'999'999'999'990},
528  {Number{9'999'999'999'999'999, 2}, 999'999'999'999'999'900},
529  {Number{-9'999'999'999'999'999, 2}, -999'999'999'999'999'900},
530  {Number{15, -1}, 1},
531  {Number{14, -1}, 1},
532  {Number{16, -1}, 1},
533  {Number{25, -1}, 2},
534  {Number{6, -1}, 0},
535  {Number{5, -1}, 0},
536  {Number{4, -1}, 0},
537  {Number{-15, -1}, -1},
538  {Number{-14, -1}, -1},
539  {Number{-16, -1}, -1},
540  {Number{-25, -1}, -2},
541  {Number{-6, -1}, 0},
542  {Number{-5, -1}, 0},
543  {Number{-4, -1}, 0}};
544  for (auto const& [x, y] : c)
545  {
546  auto j = static_cast<std::int64_t>(x);
547  BEAST_EXPECT(j == y);
548  }
549  }
550  prev_mode = Number::setround(Number::downward);
551  BEAST_EXPECT(prev_mode == Number::towards_zero);
552  {
553  Case c[]{
554  {Number{0}, 0},
555  {Number{1}, 1},
556  {Number{2}, 2},
557  {Number{3}, 3},
558  {Number{-1}, -1},
559  {Number{-2}, -2},
560  {Number{-3}, -3},
561  {Number{10}, 10},
562  {Number{99}, 99},
563  {Number{1155}, 1155},
564  {Number{9'999'999'999'999'999, 0}, 9'999'999'999'999'999},
565  {Number{9'999'999'999'999'999, 1}, 99'999'999'999'999'990},
566  {Number{9'999'999'999'999'999, 2}, 999'999'999'999'999'900},
567  {Number{-9'999'999'999'999'999, 2}, -999'999'999'999'999'900},
568  {Number{15, -1}, 1},
569  {Number{14, -1}, 1},
570  {Number{16, -1}, 1},
571  {Number{25, -1}, 2},
572  {Number{6, -1}, 0},
573  {Number{5, -1}, 0},
574  {Number{4, -1}, 0},
575  {Number{-15, -1}, -2},
576  {Number{-14, -1}, -2},
577  {Number{-16, -1}, -2},
578  {Number{-25, -1}, -3},
579  {Number{-6, -1}, -1},
580  {Number{-5, -1}, -1},
581  {Number{-4, -1}, -1}};
582  for (auto const& [x, y] : c)
583  {
584  auto j = static_cast<std::int64_t>(x);
585  BEAST_EXPECT(j == y);
586  }
587  }
588  prev_mode = Number::setround(Number::upward);
589  BEAST_EXPECT(prev_mode == Number::downward);
590  {
591  Case c[]{
592  {Number{0}, 0},
593  {Number{1}, 1},
594  {Number{2}, 2},
595  {Number{3}, 3},
596  {Number{-1}, -1},
597  {Number{-2}, -2},
598  {Number{-3}, -3},
599  {Number{10}, 10},
600  {Number{99}, 99},
601  {Number{1155}, 1155},
602  {Number{9'999'999'999'999'999, 0}, 9'999'999'999'999'999},
603  {Number{9'999'999'999'999'999, 1}, 99'999'999'999'999'990},
604  {Number{9'999'999'999'999'999, 2}, 999'999'999'999'999'900},
605  {Number{-9'999'999'999'999'999, 2}, -999'999'999'999'999'900},
606  {Number{15, -1}, 2},
607  {Number{14, -1}, 2},
608  {Number{16, -1}, 2},
609  {Number{25, -1}, 3},
610  {Number{6, -1}, 1},
611  {Number{5, -1}, 1},
612  {Number{4, -1}, 1},
613  {Number{-15, -1}, -1},
614  {Number{-14, -1}, -1},
615  {Number{-16, -1}, -1},
616  {Number{-25, -1}, -2},
617  {Number{-6, -1}, 0},
618  {Number{-5, -1}, 0},
619  {Number{-4, -1}, 0}};
620  for (auto const& [x, y] : c)
621  {
622  auto j = static_cast<std::int64_t>(x);
623  BEAST_EXPECT(j == y);
624  }
625  }
626  bool caught = false;
627  try
628  {
629  (void)static_cast<std::int64_t>(Number{9223372036854776, 3});
630  }
631  catch (std::overflow_error const&)
632  {
633  caught = true;
634  }
635  BEAST_EXPECT(caught);
636  }
637 
638  void
639  test_squelch()
640  {
641  testcase("test_squelch");
642  Number limit{1, -6};
643  BEAST_EXPECT((squelch(Number{2, -6}, limit) == Number{2, -6}));
644  BEAST_EXPECT((squelch(Number{1, -6}, limit) == Number{1, -6}));
645  BEAST_EXPECT((squelch(Number{9, -7}, limit) == Number{0}));
646  BEAST_EXPECT((squelch(Number{-2, -6}, limit) == Number{-2, -6}));
647  BEAST_EXPECT((squelch(Number{-1, -6}, limit) == Number{-1, -6}));
648  BEAST_EXPECT((squelch(Number{-9, -7}, limit) == Number{0}));
649  }
650 
651  void
652  testToString()
653  {
654  testcase("testToString");
655  BEAST_EXPECT(to_string(Number(-2, 0)) == "-2");
656  BEAST_EXPECT(to_string(Number(0, 0)) == "0");
657  BEAST_EXPECT(to_string(Number(2, 0)) == "2");
658  BEAST_EXPECT(to_string(Number(25, -3)) == "0.025");
659  BEAST_EXPECT(to_string(Number(-25, -3)) == "-0.025");
660  BEAST_EXPECT(to_string(Number(25, 1)) == "250");
661  BEAST_EXPECT(to_string(Number(-25, 1)) == "-250");
662  BEAST_EXPECT(to_string(Number(2, 20)) == "2000000000000000e5");
663  BEAST_EXPECT(to_string(Number(-2, -20)) == "-2000000000000000e-35");
664  }
665 
666  void
667  test_relationals()
668  {
669  testcase("test_relationals");
670  BEAST_EXPECT(!(Number{100} < Number{10}));
671  BEAST_EXPECT(Number{100} > Number{10});
672  BEAST_EXPECT(Number{100} >= Number{10});
673  BEAST_EXPECT(!(Number{100} <= Number{10}));
674  }
675 
676  void
677  test_stream()
678  {
679  testcase("test_stream");
680  Number x{100};
681  std::ostringstream os;
682  os << x;
683  BEAST_EXPECT(os.str() == to_string(x));
684  }
685 
686  void
687  test_inc_dec()
688  {
689  testcase("test_inc_dec");
690  Number x{100};
691  Number y = +x;
692  BEAST_EXPECT(x == y);
693  BEAST_EXPECT(x++ == y);
694  BEAST_EXPECT(x == Number{101});
695  BEAST_EXPECT(x-- == Number{101});
696  BEAST_EXPECT(x == y);
697  }
698 
699  void
700  test_toSTAmount()
701  {
702  NumberSO stNumberSO{true};
703  Issue const issue;
704  Number const n{7'518'783'80596, -5};
705  saveNumberRoundMode const save{Number::setround(Number::to_nearest)};
706  auto res2 = STAmount{issue, n.mantissa(), n.exponent()};
707  BEAST_EXPECT(res2 == STAmount{7518784});
708 
709  Number::setround(Number::towards_zero);
710  res2 = STAmount{issue, n.mantissa(), n.exponent()};
711  BEAST_EXPECT(res2 == STAmount{7518783});
712 
713  Number::setround(Number::downward);
714  res2 = STAmount{issue, n.mantissa(), n.exponent()};
715  BEAST_EXPECT(res2 == STAmount{7518783});
716 
717  Number::setround(Number::upward);
718  res2 = STAmount{issue, n.mantissa(), n.exponent()};
719  BEAST_EXPECT(res2 == STAmount{7518784});
720  }
721 
722  void
723  run() override
724  {
725  testZero();
726  test_limits();
727  test_add();
728  test_sub();
729  test_mul();
730  test_div();
731  test_root();
732  test_power1();
733  test_power2();
734  testConversions();
735  test_to_integer();
736  test_squelch();
737  testToString();
738  test_relationals();
739  test_stream();
740  test_inc_dec();
741  test_toSTAmount();
742  }
743 };
744 
745 BEAST_DEFINE_TESTSUITE(Number, ripple_basics, ripple);
746 
747 } // namespace ripple
sstream
ripple::Number_test::test_limits
void test_limits()
Definition: Number_test.cpp:48
ripple::Number_test
Definition: Number_test.cpp:29
std::overflow_error
STL class.
ripple::saveNumberRoundMode
Definition: Number.h:365
ripple::Number::exponent
constexpr int exponent() const noexcept
Definition: Number.h:213
tuple
ripple::Number_test::testZero
void testZero()
Definition: Number_test.cpp:33
ripple::Number_test::test_add
void test_add()
Definition: Number_test.cpp:84
ripple::Number_test::run
void run() override
Definition: Number_test.cpp:723
ripple::Number
Definition: Number.h:36
ripple::Number::setround
static rounding_mode setround(rounding_mode mode)
Definition: Number.cpp:47
ripple::Number::towards_zero
@ towards_zero
Definition: Number.h:161
ripple::Number::upward
@ upward
Definition: Number.h:161
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::numeric_limits::max
T max(T... args)