rippled
Number.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/Number.h>
21 #include <boost/predef.h>
22 #include <algorithm>
23 #include <cassert>
24 #include <numeric>
25 #include <stdexcept>
26 #include <type_traits>
27 #include <utility>
28 
29 #ifdef BOOST_COMP_MSVC
30 #include <boost/multiprecision/cpp_int.hpp>
31 using uint128_t = boost::multiprecision::uint128_t;
32 #else // !defined(_MSVC_LANG)
33 using uint128_t = __uint128_t;
34 #endif // !defined(_MSVC_LANG)
35 
36 namespace ripple {
37 
39 
42 {
43  return mode_;
44 }
45 
48 {
49  return std::exchange(mode_, mode);
50 }
51 
52 // Guard
53 
54 // The Guard class is used to tempoarily add extra digits of
55 // preicision to an operation. This enables the final result
56 // to be correctly rounded to the internal precision of Number.
57 
59 {
60  std::uint64_t digits_; // 16 decimal guard digits
61  std::uint8_t xbit_ : 1; // has a non-zero digit been shifted off the end
62  std::uint8_t sbit_ : 1; // the sign of the guard digits
63 
64 public:
65  explicit Guard() : digits_{0}, xbit_{0}, sbit_{0}
66  {
67  }
68 
69  // set & test the sign bit
70  void
71  set_positive() noexcept;
72  void
73  set_negative() noexcept;
74  bool
75  is_negative() const noexcept;
76 
77  // add a digit
78  void
79  push(unsigned d) noexcept;
80 
81  // recover a digit
82  unsigned
83  pop() noexcept;
84 
85  // Indicate round direction: 1 is up, -1 is down, 0 is even
86  // This enables the client to round towards nearest, and on
87  // tie, round towards even.
88  int
89  round() noexcept;
90 };
91 
92 inline void
94 {
95  sbit_ = 0;
96 }
97 
98 inline void
100 {
101  sbit_ = 1;
102 }
103 
104 inline bool
106 {
107  return sbit_ == 1;
108 }
109 
110 inline void
111 Number::Guard::push(unsigned d) noexcept
112 {
113  xbit_ = xbit_ || (digits_ & 0x0000'0000'0000'000F) != 0;
114  digits_ >>= 4;
115  digits_ |= (d & 0x0000'0000'0000'000FULL) << 60;
116 }
117 
118 inline unsigned
120 {
121  unsigned d = (digits_ & 0xF000'0000'0000'0000) >> 60;
122  digits_ <<= 4;
123  return d;
124 }
125 
126 // Returns:
127 // -1 if Guard is less than half
128 // 0 if Guard is exactly half
129 // 1 if Guard is greater than half
130 int
131 Number::Guard::round() noexcept
132 {
133  auto mode = Number::getround();
134 
135  if (mode == towards_zero)
136  return -1;
137 
138  if (mode == downward)
139  {
140  if (sbit_)
141  {
142  if (digits_ > 0 || xbit_)
143  return 1;
144  }
145  return -1;
146  }
147 
148  if (mode == upward)
149  {
150  if (sbit_)
151  return -1;
152  if (digits_ > 0 || xbit_)
153  return 1;
154  return -1;
155  }
156 
157  // assume round to nearest if mode is not one of the predefined values
158  if (digits_ > 0x5000'0000'0000'0000)
159  return 1;
160  if (digits_ < 0x5000'0000'0000'0000)
161  return -1;
162  if (xbit_)
163  return 1;
164  return 0;
165 }
166 
167 // Number
168 
169 constexpr Number one{1000000000000000, -15, Number::unchecked{}};
170 
171 void
172 Number::normalize()
173 {
174  if (mantissa_ == 0)
175  {
176  *this = Number{};
177  return;
178  }
179  bool const negative = (mantissa_ < 0);
180  auto m = static_cast<std::make_unsigned_t<rep>>(mantissa_);
181  if (negative)
182  m = -m;
183  while ((m < minMantissa) && (exponent_ > minExponent))
184  {
185  m *= 10;
186  --exponent_;
187  }
188  Guard g;
189  if (negative)
190  g.set_negative();
191  while (m > maxMantissa)
192  {
193  if (exponent_ >= maxExponent)
194  throw std::overflow_error("Number::normalize 1");
195  g.push(m % 10);
196  m /= 10;
197  ++exponent_;
198  }
199  mantissa_ = m;
200  if ((exponent_ < minExponent) || (mantissa_ < minMantissa))
201  {
202  *this = Number{};
203  return;
204  }
205 
206  auto r = g.round();
207  if (r == 1 || (r == 0 && (mantissa_ & 1) == 1))
208  {
209  ++mantissa_;
210  if (mantissa_ > maxMantissa)
211  {
212  mantissa_ /= 10;
213  ++exponent_;
214  }
215  }
216  if (exponent_ > maxExponent)
217  throw std::overflow_error("Number::normalize 2");
218 
219  if (negative)
220  mantissa_ = -mantissa_;
221 }
222 
223 Number&
224 Number::operator+=(Number const& y)
225 {
226  if (y == Number{})
227  return *this;
228  if (*this == Number{})
229  {
230  *this = y;
231  return *this;
232  }
233  if (*this == -y)
234  {
235  *this = Number{};
236  return *this;
237  }
238  assert(isnormal() && y.isnormal());
239  auto xm = mantissa();
240  auto xe = exponent();
241  int xn = 1;
242  if (xm < 0)
243  {
244  xm = -xm;
245  xn = -1;
246  }
247  auto ym = y.mantissa();
248  auto ye = y.exponent();
249  int yn = 1;
250  if (ym < 0)
251  {
252  ym = -ym;
253  yn = -1;
254  }
255  Guard g;
256  if (xe < ye)
257  {
258  if (xn == -1)
259  g.set_negative();
260  do
261  {
262  g.push(xm % 10);
263  xm /= 10;
264  ++xe;
265  } while (xe < ye);
266  }
267  else if (xe > ye)
268  {
269  if (yn == -1)
270  g.set_negative();
271  do
272  {
273  g.push(ym % 10);
274  ym /= 10;
275  ++ye;
276  } while (xe > ye);
277  }
278  if (xn == yn)
279  {
280  xm += ym;
281  if (xm > maxMantissa)
282  {
283  g.push(xm % 10);
284  xm /= 10;
285  ++xe;
286  }
287  auto r = g.round();
288  if (r == 1 || (r == 0 && (xm & 1) == 1))
289  {
290  ++xm;
291  if (xm > maxMantissa)
292  {
293  xm /= 10;
294  ++xe;
295  }
296  }
297  if (xe > maxExponent)
298  throw std::overflow_error("Number::addition overflow");
299  }
300  else
301  {
302  if (xm > ym)
303  {
304  xm = xm - ym;
305  }
306  else
307  {
308  xm = ym - xm;
309  xe = ye;
310  xn = yn;
311  }
312  while (xm < minMantissa)
313  {
314  xm *= 10;
315  xm -= g.pop();
316  --xe;
317  }
318  auto r = g.round();
319  if (r == 1 || (r == 0 && (xm & 1) == 1))
320  {
321  --xm;
322  if (xm < minMantissa)
323  {
324  xm *= 10;
325  --xe;
326  }
327  }
328  if (xe < minExponent)
329  {
330  xm = 0;
331  xe = Number{}.exponent_;
332  }
333  }
334  mantissa_ = xm * xn;
335  exponent_ = xe;
336  return *this;
337 }
338 
339 // Optimization equivalent to:
340 // auto r = static_cast<unsigned>(u % 10);
341 // u /= 10;
342 // return r;
343 // Derived from Hacker's Delight Second Edition Chapter 10
344 // by Henry S. Warren, Jr.
345 static inline unsigned
346 divu10(uint128_t& u)
347 {
348  // q = u * 0.75
349  auto q = (u >> 1) + (u >> 2);
350  // iterate towards q = u * 0.8
351  q += q >> 4;
352  q += q >> 8;
353  q += q >> 16;
354  q += q >> 32;
355  q += q >> 64;
356  // q /= 8 approximately == u / 10
357  q >>= 3;
358  // r = u - q * 10 approximately == u % 10
359  auto r = static_cast<unsigned>(u - ((q << 3) + (q << 1)));
360  // correction c is 1 if r >= 10 else 0
361  auto c = (r + 6) >> 4;
362  u = q + c;
363  r -= c * 10;
364  return r;
365 }
366 
367 Number&
369 {
370  if (*this == Number{})
371  return *this;
372  if (y == Number{})
373  {
374  *this = y;
375  return *this;
376  }
377  assert(isnormal() && y.isnormal());
378  auto xm = mantissa();
379  auto xe = exponent();
380  int xn = 1;
381  if (xm < 0)
382  {
383  xm = -xm;
384  xn = -1;
385  }
386  auto ym = y.mantissa();
387  auto ye = y.exponent();
388  int yn = 1;
389  if (ym < 0)
390  {
391  ym = -ym;
392  yn = -1;
393  }
394  auto zm = uint128_t(xm) * uint128_t(ym);
395  auto ze = xe + ye;
396  auto zn = xn * yn;
397  Guard g;
398  if (zn == -1)
399  g.set_negative();
400  while (zm > maxMantissa)
401  {
402  // The following is optimization for:
403  // g.push(static_cast<unsigned>(zm % 10));
404  // zm /= 10;
405  g.push(divu10(zm));
406  ++ze;
407  }
408  xm = static_cast<rep>(zm);
409  xe = ze;
410  auto r = g.round();
411  if (r == 1 || (r == 0 && (xm & 1) == 1))
412  {
413  ++xm;
414  if (xm > maxMantissa)
415  {
416  xm /= 10;
417  ++xe;
418  }
419  }
420  if (xe < minExponent)
421  {
422  xm = 0;
423  xe = Number{}.exponent_;
424  }
425  if (xe > maxExponent)
426  throw std::overflow_error(
427  "Number::multiplication overflow : exponent is " +
428  std::to_string(xe));
429  mantissa_ = xm * zn;
430  exponent_ = xe;
431  assert(isnormal() || *this == Number{});
432  return *this;
433 }
434 
435 Number&
437 {
438  if (y == Number{})
439  throw std::overflow_error("Number: divide by 0");
440  if (*this == Number{})
441  return *this;
442  int np = 1;
443  auto nm = mantissa();
444  auto ne = exponent();
445  if (nm < 0)
446  {
447  nm = -nm;
448  np = -1;
449  }
450  int dp = 1;
451  auto dm = y.mantissa();
452  auto de = y.exponent();
453  if (dm < 0)
454  {
455  dm = -dm;
456  dp = -1;
457  }
458  // Shift by 10^17 gives greatest precision while not overflowing uint128_t
459  // or the cast back to int64_t
460  const uint128_t f = 100'000'000'000'000'000;
461  mantissa_ = static_cast<std::int64_t>(uint128_t(nm) * f / uint128_t(dm));
462  exponent_ = ne - de - 17;
463  mantissa_ *= np * dp;
464  normalize();
465  return *this;
466 }
467 
468 Number::operator rep() const
469 {
470  rep drops = mantissa_;
471  int offset = exponent_;
472  Guard g;
473  if (drops != 0)
474  {
475  if (drops < 0)
476  {
477  g.set_negative();
478  drops = -drops;
479  }
480  for (; offset < 0; ++offset)
481  {
482  g.push(drops % 10);
483  drops /= 10;
484  }
485  for (; offset > 0; --offset)
486  {
487  if (drops > std::numeric_limits<decltype(drops)>::max() / 10)
488  throw std::overflow_error("Number::operator rep() overflow");
489  drops *= 10;
490  }
491  auto r = g.round();
492  if (r == 1 || (r == 0 && (drops & 1) == 1))
493  {
494  ++drops;
495  }
496  if (g.is_negative())
497  drops = -drops;
498  }
499  return drops;
500 }
501 
502 Number::operator XRPAmount() const
503 {
504  return XRPAmount{static_cast<rep>(*this)};
505 }
506 
507 std::string
508 to_string(Number const& amount)
509 {
510  // keep full internal accuracy, but make more human friendly if possible
511  if (amount == Number{})
512  return "0";
513 
514  auto const exponent = amount.exponent();
515  auto mantissa = amount.mantissa();
516 
517  // Use scientific notation for exponents that are too small or too large
518  if (((exponent != 0) && ((exponent < -25) || (exponent > -5))))
519  {
520  std::string ret = std::to_string(mantissa);
521  ret.append(1, 'e');
522  ret.append(std::to_string(exponent));
523  return ret;
524  }
525 
526  bool negative = false;
527 
528  if (mantissa < 0)
529  {
530  mantissa = -mantissa;
531  negative = true;
532  }
533 
534  assert(exponent + 43 > 0);
535 
536  ptrdiff_t const pad_prefix = 27;
537  ptrdiff_t const pad_suffix = 23;
538 
539  std::string const raw_value(std::to_string(mantissa));
540  std::string val;
541 
542  val.reserve(raw_value.length() + pad_prefix + pad_suffix);
543  val.append(pad_prefix, '0');
544  val.append(raw_value);
545  val.append(pad_suffix, '0');
546 
547  ptrdiff_t const offset(exponent + 43);
548 
549  auto pre_from(val.begin());
550  auto const pre_to(val.begin() + offset);
551 
552  auto const post_from(val.begin() + offset);
553  auto post_to(val.end());
554 
555  // Crop leading zeroes. Take advantage of the fact that there's always a
556  // fixed amount of leading zeroes and skip them.
557  if (std::distance(pre_from, pre_to) > pad_prefix)
558  pre_from += pad_prefix;
559 
560  assert(post_to >= post_from);
561 
562  pre_from = std::find_if(pre_from, pre_to, [](char c) { return c != '0'; });
563 
564  // Crop trailing zeroes. Take advantage of the fact that there's always a
565  // fixed amount of trailing zeroes and skip them.
566  if (std::distance(post_from, post_to) > pad_suffix)
567  post_to -= pad_suffix;
568 
569  assert(post_to >= post_from);
570 
571  post_to = std::find_if(
573  std::make_reverse_iterator(post_from),
574  [](char c) { return c != '0'; })
575  .base();
576 
577  std::string ret;
578 
579  if (negative)
580  ret.append(1, '-');
581 
582  // Assemble the output:
583  if (pre_from == pre_to)
584  ret.append(1, '0');
585  else
586  ret.append(pre_from, pre_to);
587 
588  if (post_to != post_from)
589  {
590  ret.append(1, '.');
591  ret.append(post_from, post_to);
592  }
593 
594  return ret;
595 }
596 
597 // Returns f^n
598 // Uses a log_2(n) number of multiplications
599 
600 Number
601 power(Number const& f, unsigned n)
602 {
603  if (n == 0)
604  return one;
605  if (n == 1)
606  return f;
607  auto r = power(f, n / 2);
608  r *= r;
609  if (n % 2 != 0)
610  r *= f;
611  return r;
612 }
613 
614 // Returns f^(1/d)
615 // Uses Newton–Raphson iterations until the result stops changing
616 // to find the non-negative root of the polynomial g(x) = x^d - f
617 
618 // This function, and power(Number f, unsigned n, unsigned d)
619 // treat corner cases such as 0 roots as advised by Annex F of
620 // the C standard, which itself is consistent with the IEEE
621 // floating point standards.
622 
623 Number
624 root(Number f, unsigned d)
625 {
626  if (f == one || d == 1)
627  return f;
628  if (d == 0)
629  {
630  if (f == -one)
631  return one;
632  if (abs(f) < one)
633  return Number{};
634  throw std::overflow_error("Number::root infinity");
635  }
636  if (f < Number{} && d % 2 == 0)
637  throw std::overflow_error("Number::root nan");
638  if (f == Number{})
639  return f;
640 
641  // Scale f into the range (0, 1) such that f's exponent is a multiple of d
642  auto e = f.exponent() + 16;
643  auto const di = static_cast<int>(d);
644  auto ex = [e = e, di = di]() // Euclidean remainder of e/d
645  {
646  int k = (e >= 0 ? e : e - (di - 1)) / di;
647  int k2 = e - k * di;
648  if (k2 == 0)
649  return 0;
650  return di - k2;
651  }();
652  e += ex;
653  f = Number{f.mantissa(), f.exponent() - e}; // f /= 10^e;
654  bool neg = false;
655  if (f < Number{})
656  {
657  neg = true;
658  f = -f;
659  }
660 
661  // Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
662  auto const D = ((6 * di + 11) * di + 6) * di + 1;
663  auto const a0 = 3 * di * ((2 * di - 3) * di + 1);
664  auto const a1 = 24 * di * (2 * di - 1);
665  auto const a2 = -30 * (di - 1) * di;
666  Number r = ((Number{a2} * f + Number{a1}) * f + Number{a0}) / Number{D};
667  if (neg)
668  {
669  f = -f;
670  r = -r;
671  }
672 
673  // Newton–Raphson iteration of f^(1/d) with initial guess r
674  // halt when r stops changing, checking for bouncing on the last iteration
675  Number rm1{};
676  Number rm2{};
677  do
678  {
679  rm2 = rm1;
680  rm1 = r;
681  r = (Number(d - 1) * r + f / power(r, d - 1)) / Number(d);
682  } while (r != rm1 && r != rm2);
683 
684  // return r * 10^(e/d) to reverse scaling
685  return Number{r.mantissa(), r.exponent() + e / di};
686 }
687 
688 Number
690 {
691  if (f == one)
692  return f;
693  if (f < Number{})
694  throw std::overflow_error("Number::root nan");
695  if (f == Number{})
696  return f;
697 
698  // Scale f into the range (0, 1) such that f's exponent is a multiple of d
699  auto e = f.exponent() + 16;
700  if (e % 2 != 0)
701  ++e;
702  f = Number{f.mantissa(), f.exponent() - e}; // f /= 10^e;
703 
704  // Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
705  auto const D = 105;
706  auto const a0 = 18;
707  auto const a1 = 144;
708  auto const a2 = -60;
709  Number r = ((Number{a2} * f + Number{a1}) * f + Number{a0}) / Number{D};
710 
711  // Newton–Raphson iteration of f^(1/2) with initial guess r
712  // halt when r stops changing, checking for bouncing on the last iteration
713  Number rm1{};
714  Number rm2{};
715  do
716  {
717  rm2 = rm1;
718  rm1 = r;
719  r = (r + f / r) / Number(2);
720  } while (r != rm1 && r != rm2);
721 
722  // return r * 10^(e/2) to reverse scaling
723  return Number{r.mantissa(), r.exponent() + e / 2};
724 }
725 
726 // Returns f^(n/d)
727 
728 Number
729 power(Number const& f, unsigned n, unsigned d)
730 {
731  if (f == one)
732  return f;
733  auto g = std::gcd(n, d);
734  if (g == 0)
735  throw std::overflow_error("Number::power nan");
736  if (d == 0)
737  {
738  if (f == -one)
739  return one;
740  if (abs(f) < one)
741  return Number{};
742  // abs(f) > one
743  throw std::overflow_error("Number::power infinity");
744  }
745  if (n == 0)
746  return one;
747  n /= g;
748  d /= g;
749  if ((n % 2) == 1 && (d % 2) == 0 && f < Number{})
750  throw std::overflow_error("Number::power nan");
751  return root(power(f, n), d);
752 }
753 
754 } // namespace ripple
ripple::Number::getround
static rounding_mode getround()
Definition: Number.cpp:41
ripple::root2
Number root2(Number f)
Definition: Number.cpp:689
ripple::Number::maxMantissa
constexpr static std::int64_t maxMantissa
Definition: Number.h:178
std::string
STL class.
ripple::Number::Guard::pop
unsigned pop() noexcept
Definition: Number.cpp:119
utility
std::overflow_error
STL class.
ripple::Number::Guard::digits_
std::uint64_t digits_
Definition: Number.cpp:60
std::find_if
T find_if(T... args)
ripple::Number::operator*=
Number & operator*=(Number const &x)
Definition: Number.cpp:368
ripple::Number::Guard::push
void push(unsigned d) noexcept
Definition: Number.cpp:111
std::distance
T distance(T... args)
ripple::Number::exponent
constexpr int exponent() const noexcept
Definition: Number.h:213
ripple::Number::isnormal
constexpr bool isnormal() const noexcept
Definition: Number.h:319
ripple::Number::Guard::is_negative
bool is_negative() const noexcept
Definition: Number.cpp:105
ripple::Number::Guard::set_positive
void set_positive() noexcept
Definition: Number.cpp:93
ripple::Number::rounding_mode
rounding_mode
Definition: Number.h:161
algorithm
stdexcept
ripple::Number::exponent_
int exponent_
Definition: Number.h:40
ripple::Number
Definition: Number.h:36
ripple::Number::mode_
static thread_local rounding_mode mode_
Definition: Number.h:169
ripple::Number::setround
static rounding_mode setround(rounding_mode mode)
Definition: Number.cpp:47
ripple::Number::maxExponent
constexpr static int maxExponent
Definition: Number.h:182
std::to_string
T to_string(T... args)
std::uint64_t
std::gcd
T gcd(T... args)
std::string::append
T append(T... args)
ripple::power
Number power(Number const &f, unsigned n)
Definition: Number.cpp:601
ripple::Number::Guard::sbit_
std::uint8_t sbit_
Definition: Number.cpp:62
ripple::Number::minExponent
constexpr static int minExponent
Definition: Number.h:181
ripple::one
constexpr Number one
Definition: Number.cpp:169
ripple::Number::Guard::Guard
Guard()
Definition: Number.cpp:65
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::exchange
T exchange(T... args)
ripple::Number::operator/=
Number & operator/=(Number const &x)
Definition: Number.cpp:436
ripple::abs
constexpr Number abs(Number x) noexcept
Definition: Number.h:327
ripple::Number::mantissa_
rep mantissa_
Definition: Number.h:39
cassert
ripple::Number::Number
constexpr Number()=default
ripple::Number::Guard
Definition: Number.cpp:58
ripple::Number::Guard::xbit_
std::uint8_t xbit_
Definition: Number.cpp:61
numeric
std::make_reverse_iterator
T make_reverse_iterator(T... args)
ripple::Number::mantissa
constexpr rep mantissa() const noexcept
Definition: Number.h:207
type_traits
ripple::Number::to_nearest
@ to_nearest
Definition: Number.h:161
ripple::Number::Guard::set_negative
void set_negative() noexcept
Definition: Number.cpp:99
ripple::Number::Guard::round
int round() noexcept
Definition: Number.cpp:131
ripple::divu10
static unsigned divu10(uint128_t &u)
Definition: Number.cpp:346
ripple::root
Number root(Number f, unsigned d)
Definition: Number.cpp:624
ripple::OperatingMode::FULL
@ FULL
we have the ledger and can even validate