xrpld
Loading...
Searching...
No Matches
libxrpl/basics/Number.cpp
1#include <xrpl/basics/Number.h>
2
3#include <xrpl/basics/contract.h>
4#include <xrpl/beast/utility/instrumentation.h>
5
6#include <algorithm>
7#include <cstddef>
8#include <cstdint>
9#include <functional>
10#include <iterator>
11#include <limits>
12#include <numeric>
13#include <set>
14#include <stdexcept>
15#include <string>
16#include <type_traits>
17#include <utility>
18
19#ifdef _MSC_VER
20#pragma message("Using boost::multiprecision::uint128_t and int128_t")
21#include <boost/multiprecision/cpp_int.hpp>
22using uint128_t = boost::multiprecision::uint128_t;
23using int128_t = boost::multiprecision::int128_t;
24#else // !defined(_MSC_VER)
25using uint128_t = __uint128_t;
26using int128_t = __int128_t;
27#endif // !defined(_MSC_VER)
28
29namespace xrpl {
30
32thread_local std::reference_wrapper<MantissaRange const> Number::kRange =
34
35std::string
37{
38 switch (scale)
39 {
41 return "Small";
43 return "LargeLegacy";
45 return "Large320";
47 return "Large330";
48 default:
49 throw std::runtime_error("Bad scale"); // LCOV_EXCL_LINE
50 }
51}
52
55{
56 switch (round)
57 {
59 return "ToNearest";
61 return "TowardsZero";
63 return "Downward";
65 return "Upward";
66 default:
67 throw std::runtime_error("Bad rounding mode"); // LCOV_EXCL_LINE
68 }
69}
70
71constexpr MantissaRange const&
73{
74 static constexpr MantissaRange kSmall{MantissaScale::Small};
75 static constexpr MantissaRange kLegacy{MantissaScale::LargeLegacy};
76 static constexpr MantissaRange kLarge320{MantissaScale::Large320};
77 static constexpr MantissaRange kLarge330{MantissaScale::Large330};
78
79 switch (scale)
80 {
82 return kSmall;
84 return kLegacy;
86 return kLarge320;
88 return kLarge330;
89 }
90 throw std::logic_error("Unknown mantissa scale");
91
92 // static_asserts are checked at compile time, so it doesn't matter where in the function they
93 // are located. For readability of the main body, put them after it.
94
95 // Small
96 static_assert(isPowerOfTen(kSmall.min));
97 static_assert(kSmall.min == 1'000'000'000'000'000LL);
98 static_assert(kSmall.max == 9'999'999'999'999'999LL);
99 static_assert(kSmall.log == 15);
100 static_assert(kSmall.min < Number::kMaxRep);
101 static_assert(kSmall.max < Number::kMaxRep);
102 static_assert(kSmall.cuspRoundingFix == CuspRoundingFix::Disabled);
103
104 // LargeLegacy
105 static_assert(isPowerOfTen(kLegacy.min));
106 static_assert(kLegacy.min == 1'000'000'000'000'000'000ULL);
107 static_assert(kLegacy.max == rep(9'999'999'999'999'999'999ULL));
108 static_assert(kLegacy.log == 18);
109 static_assert(kLegacy.min < Number::kMaxRep);
110 static_assert(kLegacy.max > Number::kMaxRep);
111 static_assert(kLegacy.cuspRoundingFix == CuspRoundingFix::Disabled);
112
113 // Large320
114 static_assert(isPowerOfTen(kLarge320.min));
115 static_assert(kLarge320.min == 1'000'000'000'000'000'000ULL);
116 static_assert(kLarge320.max == rep(9'999'999'999'999'999'999ULL));
117 static_assert(kLarge320.log == 18);
118 static_assert(kLarge320.min < Number::kMaxRep);
119 static_assert(kLarge320.max > Number::kMaxRep);
120 static_assert(kLarge320.cuspRoundingFix == CuspRoundingFix::Enabled320);
121
122 // Large330
123 static_assert(isPowerOfTen(kLarge330.min));
124 static_assert(kLarge330.min == 1'000'000'000'000'000'000ULL);
125 static_assert(kLarge330.max == rep(9'999'999'999'999'999'999ULL));
126 static_assert(kLarge330.log == 18);
127 static_assert(kLarge330.min < Number::kMaxRep);
128 static_assert(kLarge330.max > Number::kMaxRep);
129 static_assert(kLarge330.cuspRoundingFix == CuspRoundingFix::Enabled330);
130}
131
134{
135 return mode;
136}
137
140{
141 return std::exchange(Number::mode, inMode);
142}
143
146{
147 return kRange.get().scale;
148}
149
150void
157
158// Optimization equivalent to:
159// auto r = static_cast<unsigned>(u % 10);
160// u /= 10;
161// return r;
162// Derived from Hacker's Delight Second Edition Chapter 10
163// by Henry S. Warren, Jr.
164static inline unsigned
165divu10(uint128_t& u)
166{
167 // q = u * 0.75
168 auto q = (u >> 1) + (u >> 2);
169 // iterate towards q = u * 0.8
170 q += q >> 4;
171 q += q >> 8;
172 q += q >> 16;
173 q += q >> 32;
174 q += q >> 64;
175 // q /= 8 approximately == u / 10
176 q >>= 3;
177 // r = u - q * 10 approximately == u % 10
178 auto r = static_cast<unsigned>(u - ((q << 3) + (q << 1)));
179 // correction c is 1 if r >= 10 else 0
180 auto c = (r + 6) >> 4;
181 u = q + c;
182 r -= c * 10;
183 return r;
184}
185
186template <class T>
188
220{
221 std::uint64_t digits_{0}; // 16 decimal guard digits
222 std::uint8_t xbit_ : 1 {0}; // has a non-zero digit been shifted off the end
223 std::uint8_t sbit_ : 1 {0}; // the sign of the guard digits
224
225public:
229
237
241
242 // set & test the sign bit
243 void
244 setPositive() noexcept;
245 void
246 setNegative() noexcept;
247 // Should only be called by doNormalize, and then only for division
248 // operations with remainders.
249 void
250 setDropped() noexcept;
251 [[nodiscard]] bool
252 isNegative() const noexcept;
253
254 // add a digit
255 template <class T>
256 void
257 push(T d) noexcept;
258
259 // recover a digit
260 unsigned
261 pop() noexcept;
262
263 // if true, there are no digits in the guard, including dropped digits (xbit_)
264 [[nodiscard]] bool
265 empty() const noexcept;
266
276 template <class T>
277 void
278 doDropDigit(T& mantissa, int& exponent) noexcept;
279
280 // Modify the result to the correctly rounded value
281 template <UnsignedMantissa T>
282 void
283 doRoundUp(bool& negative, T& mantissa, int& exponent, std::string location);
284
285 // Modify the result to the correctly rounded value
286 template <UnsignedMantissa T>
287 void
288 doRoundDown(bool& negative, T& mantissa, int& exponent) const;
289
290 // Modify the result to the correctly rounded value
291 void
292 doRound(rep& drops, std::string location) const;
293
294private:
295 template <UnsignedMantissa T>
296 void
297 pushOverflow(T mantissa);
298
299 enum class Round {
300 // The result is exact. No rounding is needed. Only used if cuspRoundingFix is Enabled330 or
301 // higher.
302 Exact = -2,
303 // Round down. Since we use integer math, that usually means no change is needed.
304 // Exceptions are for when the result is between kMaxRep and kMaxRepUp (round to kMaxRep),
305 // or after subtraction where _any_ remainder will modify the result. The latter is what
306 // distinguishes Exact from Down.
307 Down = -1,
308 // The result was exactly half-way between two integers. This will round to even.
309 Even = 0,
310 // Round up. Always adds 1 (or subtracts 1 in some cases if cuspRoundingFix is not
311 // Enabled330)
312 Up = 1,
313 };
314
315 // Indicate round direction. See Round enum above.
316 // This enables the client to round towards nearest, and on
317 // tie, round towards even.
318 [[nodiscard]] Round
319 round() const noexcept;
320
321 void
322 doPush(unsigned d) noexcept;
323
324 template <UnsignedMantissa T>
325 void
326 bringIntoRange(bool& negative, T& mantissa, int& exponent) const;
327};
328
329inline void
331{
332 sbit_ = 0;
333}
334
335inline void
337{
338 sbit_ = 1;
339}
340
341inline void
343{
344 xbit_ = 1;
345}
346
347inline bool
349{
350 return sbit_ == 1;
351}
352
353inline void
354Number::Guard::doPush(unsigned d) noexcept
355{
356 XRPL_ASSERT(d < 10, "xrpl::Number::Guard::doPush : valid digit");
357 xbit_ = xbit_ || ((digits_ & 0x0000'0000'0000'000F) != 0);
358 digits_ >>= 4;
359 digits_ |= (d & 0x0000'0000'0000'000FULL) << 60;
360}
361
362template <class T>
363inline void
365{
366 doPush(static_cast<unsigned>(d));
367}
368
369inline unsigned
371{
372 unsigned const d = (digits_ & 0xF000'0000'0000'0000) >> 60;
373 digits_ <<= 4;
374 return d;
375}
376
377inline bool
378Number::Guard::empty() const noexcept
379{
380 return digits_ == 0 && !xbit_;
381}
382
383template <class T>
384void
386{
387 push(mantissa % 10);
388 mantissa /= 10;
389 ++exponent;
390}
391
392// Use the divu10 optimization for uint128s
393template <>
394void
396{
397 // The following is optimization for:
398 // push(static_cast<unsigned>(mantissa % 10));
399 // mantissa /= 10;
401 ++exponent;
402}
403
404template <UnsignedMantissa T>
405void
407{
408 XRPL_ASSERT(mantissa <= kMaxRepUp, "xrpl::Number::Guard::pushOverflow : valid mantissa");
411 {
412 // Special case rounding rules for the values in the range [kMaxRep, kMaxRepUp).
413
414 auto constexpr spread = kMaxRepUp - kMaxRep;
415 static_assert(spread == 3);
416
417 // Round in two steps.
418
419 // The first step uses the digits _already_ in the Guard to possibly round the mantissa up.
420 // Ultimately, the purpose of this step is to capture rounding where the stored digits would
421 // change the decision without those digits. (e.g. From just _below_ the midpoint to just
422 // _above_ the midpoint for ToNearest, or from kMaxRep into the in-between for Upward. Make
423 // an exception if the final digit is 9, because it can only get larger, and we don't want
424 // to bump up to kMaxRepUp.
425 if (mantissa % 10 < 9)
426 {
427 // Intentionally use integer math to get the largest value under the midpoint.
428 auto constexpr kMidpoint = kMaxRep + (spread / 2);
429 static_assert(kMidpoint == kMaxRep + 1);
430 auto const r = round();
431 if (r == Round::Up || (r == Round::Even && mantissa == kMidpoint))
432 {
433 ++mantissa;
434 }
435 }
436
437 // The second step scales the final digit of the updated mantissa proportionally, converting
438 // from (kMaxRep, kMaxRepUp) to (0 to 9]. It then pushes that scaled digit onto the guard as
439 // if it was a digit that got removed, but doesn't actually remove it. This method should be
440 // future-proof in case the number of mantissa bits ever changes. (Though for integer values
441 // of the form 2^(2^x-1), the spread will always be the same.) Effects:
442 // * For round to nearest
443 // * if the updated mantissa is below the midpoint, it'll round "down" to kMaxRep
444 // * if above the midpoint, it'll round "up" to kMaxRepUp
445 // * it can never be exactly at the midpoint, because kMaxRepUp is always even, and
446 // kMaxRep is always odd, so don't worry about that case.
447 // * For round upward, will round up to kMaxRepUp for positive values, down to kMaxRep for
448 // negative.
449 // * For round downward, does the opposite of upward.
450 // * For round toward zero, always rounds down to kMaxRep.
451
452 auto const diff = mantissa - kMaxRep;
453 auto const digit = static_cast<unsigned>((diff * 10) / spread);
454 XRPL_ASSERT(
455 digit < 10u && digit != 5, "xrpl::Number::Guard::pushOverflow : valid overflow digit");
456
457 // Don't remove the digit from the mantissa, but add it to the guard as if it was.
458 push(digit);
459 }
460}
461
462// Returns:
463// Exact if Guard is _zero_, and appropriate amendments are enabled
464// Down if Guard is less than half
465// Even if Guard is exactly half
466// Up if Guard is greater than half
468Number::Guard::round() const noexcept
469{
470 // Local "mode" shadows and has the same value as the static thread_local "Number::mode".
471 // This ensures the overhead of loading the thread_local is only incurred once.
472 auto const mode = Number::getround();
473
475 {
476 // No remainder
477 return Round::Exact;
478 }
479
481 return Round::Down;
482
483 // Also Towards Zero
485 {
486 return Round::Down;
487 }
488
489 // Away from Zero. Since we checked sbit_ in the previous block, we don't need to check it
490 // again.
492 {
493 if (empty())
494 return Round::Down;
495 return Round::Up;
496 }
497
498 XRPL_ASSERT(
499 mode == RoundingMode::ToNearest, "xrpl::Number::Guard::Round : fallthrough to ToNearest");
500 // assume round to nearest if mode is not one of the predefined values
501 if (digits_ > 0x5000'0000'0000'0000)
502 return Round::Up;
503 if (digits_ < 0x5000'0000'0000'0000)
504 return Round::Down;
505 if (xbit_)
506 return Round::Up;
507 return Round::Even;
508}
509
510template <UnsignedMantissa T>
511void
512Number::Guard::bringIntoRange(bool& negative, T& mantissa, int& exponent) const
513{
514 // Bring mantissa back into the minMantissa / maxMantissa range AFTER
515 // rounding.
516 if (mantissa < minMantissa &&
518 {
519 mantissa *= 10;
520 --exponent;
521 }
522 // mantissa should never be 0, but if it _is_ assert, but fall back to making the result kZero.
523 if (exponent < kMinExponent ||
525 {
526 // Engineers: If you hit this assert, you probably did something wrong in the operation
527 // leading up to the rounding work.
528 XRPL_ASSERT(mantissa != 0, "xrpl::Number::Guard::bringIntoRange : valid mantissa");
529 static constexpr Number kZero = Number{};
530
531 negative = kZero.negative_;
532 mantissa = kZero.mantissa_;
533 exponent = kZero.exponent_;
534 }
535}
536
537template <UnsignedMantissa T>
538void
539Number::Guard::doRoundUp(bool& negative, T& mantissa, int& exponent, std::string location)
540{
542
543 auto const r = round();
544 if (r == Round::Up || (r == Round::Even && (mantissa & 1) == 1))
545 {
546 auto const safeToIncrement = [this](auto const& mantissa) {
547 return mantissa < maxMantissa && mantissa < kMaxRep;
548 };
550 {
551 // Ensure mantissa after incrementing fits within both the
552 // min/maxMantissa range and is a valid "rep".
553 if (safeToIncrement(mantissa))
554 {
555 // Nothing unusual here, just increment the mantissa
556 ++mantissa;
557 }
558 else
559 {
562 {
563 // When rounding up a value in between kMaxRep, and kMaxRepUp, round to
564 // kMaxRepUp. Note that the decision for this rounding is dominated by the
565 // results of pushOverflow.
567 }
568 else
569 {
570 // Incrementing the mantissa will require dividing, which will require rounding.
571 // So _don't_ increment the mantissa. Instead, divide and round recursively. It
572 // should be impossible to recurse more than once, because once the mantissa is
573 // divided by 10, it will be _well_ under maxMantissa and kMaxRep, so adding 1
574 // will have no chance of bringing it back over.
576 XRPL_ASSERT_PARTS(
577 safeToIncrement(mantissa),
578 "xrpl::Number::Guard::doRoundUp",
579 "can't recurse more than once");
580 doRoundUp(negative, mantissa, exponent, location);
581 return;
582 }
583 }
584 }
585 else
586 {
587 // Need to preserve the incorrect behavior until the fix amendment can be retired,
588 // because otherwise would risk an unplanned ledger fork.
589 ++mantissa;
590 // Ensure mantissa after incrementing fits within both the
591 // min/maxMantissa range and is a valid "rep".
593 {
594 // Don't use doDropDigit here
595 mantissa /= 10;
596 ++exponent;
597 }
598 }
599 }
600 else if (
603 {
604 // When rounding down a value in between kMaxRep, and kMaxRepUp, round to kMaxRep.
605 // Note that the decision for this rounding is dominated by the results of pushOverflow.
607 }
608 bringIntoRange(negative, mantissa, exponent);
611}
612
613template <UnsignedMantissa T>
614void
615Number::Guard::doRoundDown(bool& negative, T& mantissa, int& exponent) const
616{
617 // Do not pushOverflow here.
618
619 auto r = round();
621 {
622 // If there was any remainder, subtract 1 from the result. This is sufficient to get the
623 // best rounding.
624 XRPL_ASSERT(
626 "xrpl::Number::Guard::doRoundDown : mantissa is expected size");
627 if (r != Round::Exact)
628 {
629 --mantissa;
630 }
631 }
632 else
633 {
634 // Need to preserve the incorrect behavior until the fix amendment can be retired,
635 // because otherwise would risk an unplanned ledger fork.
636 if (r == Round::Up || (r == Round::Even && (mantissa & 1) == 1))
637 {
638 --mantissa;
639 if (mantissa < minMantissa)
640 {
641 mantissa *= 10;
642 --exponent;
643 }
644 }
645 }
646 bringIntoRange(negative, mantissa, exponent);
647}
648
649// Modify the result to the correctly rounded value
650void
652{
653 // Do not pushOverflow here.
654
655 auto r = round();
656 if (r == Round::Up || (r == Round::Even && (drops & 1) == 1))
657 {
658 if (drops >= kMaxRep)
659 {
660 static_assert(sizeof(internalrep) == sizeof(rep));
661 // This should be impossible, because it's impossible to represent
662 // "kMaxRep + 0.6" in Number, regardless of the scale. There aren't
663 // enough digits available. You'd either get a mantissa of "kMaxRep"
664 // or "(kMaxRep + 1) / 10", neither of which will round up when
665 // converting to rep, though the latter might overflow _before_
666 // rounding.
667 Throw<std::overflow_error>(std::string(location)); // LCOV_EXCL_LINE
668 }
669 ++drops;
670 }
671 XRPL_ASSERT(drops >= 0, "xrpl::Number::Guard::doRound : positive magnitude");
672
673 if (isNegative())
674 drops = -drops;
675}
676
677// Number
678
679// Safely convert rep (int64) mantissa to internalrep (uint64). If the rep is
680// negative, returns the positive value. This takes a little extra work because
681// converting std::numeric_limits<std::int64_t>::min() flirts with UB, and can
682// vary across compilers.
685{
686 // If the mantissa is already positive, just return it
687 if (mantissa >= 0)
688 return mantissa;
689 // If the mantissa is negative, but fits within the positive range of rep,
690 // return it negated
692 return -mantissa;
693
694 // If the mantissa doesn't fit within the positive range, convert to
695 // int128_t, negate that, and cast it back down to the internalrep
696 // In practice, this is only going to cover the case of
697 // std::numeric_limits<rep>::min().
698 int128_t const temp = mantissa;
699 return static_cast<internalrep>(-temp);
700}
701
702Number
704{
705 auto const& range = kRange.get();
706 return Number{false, range.min, -range.log, Number::Unchecked{}};
707}
708
709template <class T>
710void
712 bool& negative,
713 T& mantissa,
714 int& exponent,
717 MantissaRange::CuspRoundingFix cuspRoundingFix,
718 bool dropped)
719{
720 static constexpr auto kMinExponent = Number::kMinExponent;
721 static constexpr auto kMaxExponent = Number::kMaxExponent;
722 auto const repLimit = cuspRoundingFix >= MantissaRange::CuspRoundingFix::Enabled330
725
726 using Guard = Number::Guard;
727
728 static constexpr Number kZero = Number{};
729 if (mantissa == 0)
730 {
731 mantissa = kZero.mantissa_;
732 exponent = kZero.exponent_;
733 negative = kZero.negative_;
734 return;
735 }
736 auto m = mantissa;
737 while ((m < minMantissa) && (exponent > kMinExponent))
738 {
739 m *= 10;
740 --exponent;
741 }
742 Guard g(minMantissa, maxMantissa, cuspRoundingFix);
743 if (negative)
744 g.setNegative();
745 if (dropped)
746 g.setDropped();
747 while (m > maxMantissa)
748 {
749 if (exponent >= kMaxExponent)
750 throw std::overflow_error("Number::normalize 1");
751 g.doDropDigit(m, exponent);
752 }
753 if ((exponent < kMinExponent) || (m < minMantissa))
754 {
755 mantissa = kZero.mantissa_;
756 exponent = kZero.exponent_;
757 negative = kZero.negative_;
758 return;
759 }
760
761 // When using the largeRange, "m" needs fit within an int64, even if
762 // the final mantissa is going to end up larger to fit within the
763 // MantissaRange. Cut it down here so that the rounding will be done while
764 // it's smaller.
765 //
766 // Example: 9,900,000,000,000,123,456 > 9,223,372,036,854,775,807,
767 // so "m" will be modified to 990,000,000,000,012,345. Then that value
768 // will be rounded to 990,000,000,000,012,345 or
769 // 990,000,000,000,012,346, depending on the rounding mode. Finally,
770 // mantissa will be "m*10" so it fits within the range, and end up as
771 // 9,900,000,000,000,123,450 or 9,900,000,000,000,123,460.
772 // mantissa() will return mantissa / 10, and exponent() will return
773 // exponent + 1.
774 if (m > repLimit)
775 {
776 if (exponent >= kMaxExponent)
777 throw std::overflow_error("Number::normalize 1.5");
778 g.doDropDigit(m, exponent);
779 }
780 // Before modification, m should be within the min/max range. After
781 // modification, it must be less than repLimit. In other words, the original
782 // value should have been no more than repLimit * 10.
783 // (repLimit * 10 > maxMantissa)
784 XRPL_ASSERT_PARTS(m <= repLimit, "xrpl::doNormalize", "intermediate mantissa fits in limit");
785 mantissa = m;
786
787 g.doRoundUp(negative, mantissa, exponent, "Number::normalize 2");
788 XRPL_ASSERT_PARTS(
790 "xrpl::doNormalize",
791 "final mantissa fits in range");
792}
793
794template <>
795void
797 bool& negative,
798 uint128_t& mantissa,
799 int& exponent,
802 MantissaRange::CuspRoundingFix cuspRoundingFix)
803{
804 // Not used by every compiler version, and thus not necessarily
805 // counted by coverage build
806 // LCOV_EXCL_START
807 doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa, cuspRoundingFix, false);
808 // LCOV_EXCL_STOP
809}
810
811template <>
812void
814 bool& negative,
815 unsigned long long& mantissa,
816 int& exponent,
819 MantissaRange::CuspRoundingFix cuspRoundingFix)
820{
821 // Not used by every compiler version, and thus not necessarily
822 // counted by coverage build
823 // LCOV_EXCL_START
824 doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa, cuspRoundingFix, false);
825 // LCOV_EXCL_STOP
826}
827
828template <>
829void
831 bool& negative,
832 unsigned long& mantissa,
833 int& exponent,
836 MantissaRange::CuspRoundingFix cuspRoundingFix)
837{
838 doNormalize(negative, mantissa, exponent, minMantissa, maxMantissa, cuspRoundingFix, false);
839}
840
841void
843{
844 normalize(negative_, mantissa_, exponent_, range.min, range.max, range.cuspRoundingFix);
845}
846
847void
849{
850 normalize(
851 negative_,
852 mantissa_,
853 exponent_,
854 guard.minMantissa,
855 guard.maxMantissa,
856 guard.cuspRoundingFix);
857}
858
859// Copy the number, but set a new exponent. Because the mantissa doesn't change,
860// the result will be "mostly" normalized, but the exponent could go out of
861// range.
862Number
863Number::shiftExponent(int exponentDelta) const
864{
865 XRPL_ASSERT_PARTS(isnormal(), "xrpl::Number::shiftExponent", "normalized");
866 auto const newExponent = exponent_ + exponentDelta;
867 if (newExponent >= kMaxExponent)
868 throw std::overflow_error("Number::shiftExponent");
869 if (newExponent < kMinExponent)
870 {
871 return Number{};
872 }
873 Number const result{negative_, mantissa_, newExponent, Unchecked{}};
874 XRPL_ASSERT_PARTS(result.isnormal(), "xrpl::Number::shiftExponent", "result is normalized");
875 return result;
876}
877
878Number&
880{
881 static constexpr Number kZero = Number{};
882 if (y == kZero)
883 return *this;
884 if (*this == kZero)
885 {
886 *this = y;
887 return *this;
888 }
889 if (*this == -y)
890 {
891 *this = kZero;
892 return *this;
893 }
894
895 XRPL_ASSERT(isnormal() && y.isnormal(), "xrpl::Number::operator+=(Number) : is normal");
896 // *n = negative
897 // *s = sign
898 // *m = mantissa
899 // *e = exponent
900
901 // Need to use uint128_t, because large mantissas can overflow when added
902 // together.
903 bool xn = negative_;
904 uint128_t xm = mantissa_;
905 auto xe = exponent_;
906
907 bool const yn = y.negative_;
908 uint128_t ym = y.mantissa_;
909 auto ye = y.exponent_;
910 Guard g(kRange);
911
912 auto const& minMantissa = g.minMantissa;
913 auto const& maxMantissa = g.maxMantissa;
914 auto const cuspRoundingFix = g.cuspRoundingFix;
915
916 auto const repLimit =
918
919 // Bring the exponents of both values into agreement, so the mantissas are on the same scale
920 // and can be added directly together.
921
922 auto const upperLimit = static_cast<uint128_t>(g.minMantissa) * 1000;
923 // For the "adjust" lambda
924 // expandM / expandE: The values for which the mantissa will be expanded, and the exponent
925 // decreased to match. Mantissa won't be expanded beyond upperLimit.
926 // (37e8 == 37000e5 == 37000000e2)
927 // shrinkM / shrinkE: The values for which the mantissa will be shrunk, and exponent increased
928 // to match, if necessary.
929 auto const adjust = [&g, &upperLimit](
930 uint128_t& expandM, int& expandE, uint128_t& shrinkM, int& shrinkE) {
931 // Adjust up and down until the exponents match
933 {
934 // For Enabled330, there are three steps.
935 // 1. First, shrink the mantissa of shrinkM/shrinkE while shrinkM ends in 0.
936 while (shrinkE < expandE && shrinkM % 10 == 0)
937 {
938 g.doDropDigit(shrinkM, shrinkE);
939 }
940
941 // 2. Then expand the mantissa of expandM/expandE, with a limit for expandM a few orders
942 // of magnitude above the MantissaRange. This will leave a few extra digits for rounding
943 // later, but nothing excessive.
944 while (shrinkE < expandE && expandE > kMinExponent && expandM < upperLimit)
945 {
946 expandM *= 10;
947 --expandE;
948 }
949 }
950
951 // 3. Finally, shrink the mantissa of shrinkM/shrinkE until the exponents match. Any removed
952 // digits will be put into the Guard. This is the only step for non-Enabled330 modes.
953 while (shrinkE < expandE)
954 {
955 g.doDropDigit(shrinkM, shrinkE);
956 }
957 };
958
959 // Shrink the mantissa and raise the exponent of the value with the lower exponent. Store any
960 // dropped digits in the Guard.
961 if (xe < ye)
962 {
963 if (xn)
964 g.setNegative();
965
966 adjust(ym, ye, xm, xe);
967 }
968 else if (xe > ye)
969 {
970 if (yn)
971 g.setNegative();
972
973 adjust(xm, xe, ym, ye);
974 }
976 {
977 // Both values have the same exponent.
978 // Set the sign of the Guard based on the sign of the Number with the smallest
979 // unsigned _mantissa_
980 if ((xm < ym && xn) || (ym < xm && yn))
981 g.setNegative();
982 }
983
984 if (xn == yn)
985 {
986 xm += ym;
987
989 {
990 // Don't do any adjustments for Enabled330. Normalize will take care of it
991 // Because of "adjust", the only way there can be data in the Guard is if we first grew
992 // the mantissa past the maxMantissa. Since we added here, it can only get bigger.
993 // If xm > maxMantissa, then doNormalize has all the data it needs from the last 3-4
994 // digits, plus the "dropped" flag that will be passed in.
995 // If not, then the mantissa will only need to be padded out with 0s and won't need to
996 // round.
997 XRPL_ASSERT(
998 xm > maxMantissa || g.empty(),
999 "xrpl::Number::operator+ : rounding state expected after add");
1000 }
1001 else
1002 {
1003 if (xm > maxMantissa || xm > repLimit)
1004 {
1005 g.doDropDigit(xm, xe);
1006 }
1007 g.doRoundUp(xn, xm, xe, "Number::addition overflow");
1008 }
1009 }
1010 else
1011 {
1012 if (xm > ym)
1013 {
1014 xm = xm - ym;
1015 }
1016 else
1017 {
1018 xm = ym - xm;
1019 xe = ye;
1020 xn = yn;
1021 }
1022 if (cuspRoundingFix >= MantissaRange::CuspRoundingFix::Enabled330)
1023 {
1024 // Because we subtracted, xm can have any number of digits from 1 up to
1025 // upperLimit * 10, and g can be in any state. (Note that xm can't be zero, because that
1026 // special case was tested earlier.)
1027
1028 // Grow xm/xe and pull digits out of the Guard until xm reaches upperLimit, but stop if
1029 // the Guard empties out, because no rounding will be necessary. This will ensure that
1030 // normalize will have enough information to make an accurate rounding decision.
1031 // (Normalize will pad a small mantissa back into range.) Note that if any digits were
1032 // lost (xbit_), the Guard will never be empty, so xm will grow larger than upperLimit.
1033 while (xm < upperLimit && !g.empty())
1034 {
1035 xm *= 10;
1036 xm -= g.pop();
1037 --xe;
1038 }
1039 XRPL_ASSERT(
1040 xm > maxMantissa || g.empty(),
1041 "xrpl::Number::operator+ : rounding state expected after subtract");
1042 }
1043 else
1044 {
1045 // Grow xm/xe and pull digits out of the Guard until it's back in the
1046 // minMantissa/maxMantissa range.
1047 while (xm < minMantissa && xm * 10 <= repLimit)
1048 {
1049 xm *= 10;
1050 xm -= g.pop();
1051 --xe;
1052 }
1053 }
1054 // Rounding down can result in decrementing xm, based on whether there is any data left in
1055 // the Guard (depending on cuspRoundingFix). Note that if that happens, then the Guard is
1056 // not empty. For Enabled330, that will also result in the "dropped" flag being passed to
1057 // doNormalize, which may result in the mantissa being incremented again. It doesn't matter
1058 // what the dropped digits are, only that they exist. This is because subtracting one
1059 // "overcorrects", so we know there are still trailing digits to be accounted for in the
1060 // rounding.
1061 //
1062 // This works because
1063 // 1. The rounding up will be done _after_ the mantissa is brought into range. It may not
1064 // be in range right now, and
1065 // 2. The "dropped" flag is only ever used as a tie-breaker, specifically when rounding
1066 // away from zero, and the dropped digits are 0, or when rounding to nearest, and
1067 // the dropped digits represent exactly 0.5.
1068 g.doRoundDown(xn, xm, xe);
1069 }
1070
1072 xn,
1073 xm,
1074 xe,
1077 cuspRoundingFix,
1078 cuspRoundingFix == MantissaRange::CuspRoundingFix::Enabled330 && !g.empty());
1079 negative_ = xn;
1080 mantissa_ = static_cast<internalrep>(xm);
1081 exponent_ = xe;
1082 XRPL_ASSERT(isnormal(), "xrpl::Number::operator+= : result is normal");
1083 return *this;
1084}
1085
1086Number&
1088{
1089 static constexpr Number kZero = Number{};
1090 if (*this == kZero)
1091 return *this;
1092 if (y == kZero)
1093 {
1094 *this = y;
1095 return *this;
1096 }
1097 // *n = negative
1098 // *s = sign
1099 // *m = mantissa
1100 // *e = exponent
1101
1102 bool const xn = negative_;
1103 int const xs = xn ? -1 : 1;
1105 auto xe = exponent_;
1106
1107 bool const yn = y.negative_;
1108 int const ys = yn ? -1 : 1;
1109 internalrep const ym = y.mantissa_;
1110 auto ye = y.exponent_;
1111
1112 auto zm = uint128_t(xm) * uint128_t(ym);
1113 auto ze = xe + ye;
1114 auto zs = xs * ys;
1115 bool zn = (zs == -1);
1116 Guard g(kRange);
1117 if (zn)
1118 g.setNegative();
1119
1120 auto const& maxMantissa = g.maxMantissa;
1121 auto const repLimit =
1123
1124 while (zm > maxMantissa || zm > repLimit)
1125 {
1126 g.doDropDigit(zm, ze);
1127 }
1128
1129 xm = static_cast<internalrep>(zm);
1130 xe = ze;
1131 g.doRoundUp(zn, xm, xe, "Number::multiplication overflow : exponent is " + std::to_string(xe));
1132 negative_ = zn;
1133 mantissa_ = xm;
1134 exponent_ = xe;
1135
1136 normalize(g);
1137 return *this;
1138}
1139
1140Number&
1142{
1143 static constexpr Number kZero = Number{};
1144 if (y == kZero)
1145 throw std::overflow_error("Number: divide by 0");
1146 if (*this == kZero)
1147 return *this;
1148 // n* = numerator
1149 // d* = denominator
1150 // z* = result (quotient)
1151 // *p = negative (p for positive, even though the value means not
1152 // positive?)
1153 // *s = sign
1154 // *m = mantissa
1155 // *e = exponent
1156
1157 bool const np = negative_;
1158 int const ns = (np ? -1 : 1);
1159 auto nm = mantissa_;
1160 auto ne = exponent_;
1161
1162 bool const dp = y.negative_;
1163 int const ds = (dp ? -1 : 1);
1164 // Create the denominator as 128-bit unsigned, since that's what we
1165 // need to work with.
1166 auto const dm = static_cast<uint128_t>(y.mantissa_);
1167 auto const de = y.exponent_;
1168
1169 auto const& range = kRange.get();
1170 auto const& minMantissa = range.min;
1171 auto const& maxMantissa = range.max;
1172 auto const cuspRoundingFix = range.cuspRoundingFix;
1173
1174 // Division operates on two large integers (16-digit for small
1175 // mantissas, 19-digit for large) using integer math. If the values
1176 // were just divided directly, the result would be only ever be one
1177 // digit or zero - not very useful.
1178 // e.g. 9'876'543'210'987'654 / 1'234'567'890'123'456 = 8
1179 // 1'234'567'890'123'456 / 9'876'543'210'987'654 = 0
1180 // Introduce a power-of-ten multiplication factor for the numerator
1181 // which will ensure the result has a meaningful number of digits.
1182 //
1183 // Consider numbers with a 2-digit mantissa:
1184 // * Assume both numbers have an exponent of 0, using "ToNearest" rounding
1185 // * 23 / 67 = 0
1186 // * Use a factor of 10^4
1187 // * 230'000 / 67 = 3432 with an exponent of -4
1188 // * The normalized result will be 34, exponent -2, or 0.34
1189 //
1190 // The most extreme results are 10/99 and 99/10
1191 // * 100'000 / 99 = 1'010e-4 = 10e-2 or 0.10
1192 // * 990'000 / 10 = 99'000e-4 = 99e-1 or 9.9
1193 //
1194 // Note that the computations give 2 or 3 digits after the
1195 // decimal point to determine which way to round for most scenarios.
1196 //
1197 // For small mantissas (where the MantissaRange.log == 15), shifting by 10^17 gives sufficient
1198 // precision while not overflowing uint128_t or the cast back to int64_t. (This is legacy
1199 // behavior, which must not be changed.)
1200 //
1201 // For large mantissas (where the MantissaRange.log == 18), a shift by 10^20 would be optimal
1202 // for most scenarios. However, larger mantissa values would overflow 2^128.
1203 //
1204 // * log(2^128,10) ~ 38.5
1205 // * largeRange.log = 18, fits in 10^19
1206 // * The expanded numerator must fit in 10^38
1207 // * f not be more than 10^(38-19) = 10^19 safely
1208 //
1209 // So, we do the division into stages:
1210 //
1211 // Stage 1: Use the same factor of 10^17, for the initial division. This
1212 // will frequently not result in a whole number quotient.
1213 //
1214 // Stage 2: If there is a remainder from the first step, repeat the
1215 // process with a "correction" factor of 10^5. Shift the
1216 // result of Stage 1 over by 5 places, and add the second result to it.
1217 // This is equivalent to if we had used an initial factor of 10^22,
1218 // a couple digits more than we actually need.
1219 //
1220 // Stage 3: If there is still a remainder, and the cuspRoundingFix
1221 // is enabled, pass a flag indicating such to doNormalize. The Guard
1222 // in doNormalize will treat that flag as if non-zero digits had
1223 // been dropped from the mantissa when shrinking it into range.
1224 // This is only relevant when rounding away from zero (Upward for
1225 // positive numbers, Downward for negative), or if the "regular"
1226 // remainder is exactly 0.5 for "ToNearest". This will give the
1227 // rounding the most accurate result possible, as if infinite
1228 // precision was used in the initial calculation.
1229
1230 // Stage 1: Do the initial division with a factor of 10^17.
1231 auto constexpr factorExponent = 17;
1232
1233 uint128_t constexpr f = kPowerOfTen[factorExponent];
1234
1235 auto const numerator = uint128_t(nm) * f;
1236
1237 auto zm = numerator / dm;
1238 auto ze = ne - de - factorExponent;
1239 bool zp = (ns * ds) < 0;
1240 // dropped is used in the same way as Guard::xbit_. In the case of
1241 // division, it indicates if there's any remainder left over after
1242 // we have been as precise as reasonable. If there is, it would be as
1243 // if we were using infinite precision math, and a non-zero digit
1244 // had been shifted off the end of the result when normalizing.
1245 bool dropped = false;
1246
1248 {
1249 // Stage 2
1250 //
1251 // If there is a remainder, treat it as a secondary numerator.
1252 // Multiply by correctionFactor separately from stage 1.
1253 // The math for this would work for small mantissas, but we need to
1254 // preserve legacy behavior.
1255 //
1256 // Consider:
1257 // ((numerator * correctionFactor) / dm) / correctionFactor
1258 // = ((numerator / dm) * correctionFactor) / correctionFactor)
1259 //
1260 // But that assumes infinite precision. With integer math, this is
1261 // equivalent to
1262 //
1263 // = ((numerator / dm * correctionFactor)
1264 // + ((numerator % dm) * correctionFactor) / dm) / correctionFactor
1265 // = ((zm * correctionFactor)
1266 // + (remainder * correctionFactor) / dm) / correctionFactor
1267 //
1268 // The trick is that multiplication by correctionFactor is done on the mantissa, but
1269 // division by correctionFactor is done by modifying the exponent, so no precision is lost
1270 // until we normalize.
1271 //
1272 // If remainder is zero, we can skip this stage entirely because
1273 // the first stage gave an exact answer.
1274 auto constexpr correctionExponent = 5;
1275 uint128_t constexpr correctionFactor = kPowerOfTen[correctionExponent];
1276 static_assert(factorExponent + correctionExponent == 22);
1277
1278 auto const remainder = (numerator % dm);
1279 if (remainder != 0)
1280 {
1281 auto const partialNumerator = remainder * correctionFactor;
1282 auto const correction = partialNumerator / dm;
1283
1284 // If the correction is zero, we do not have to make any
1285 // modifications to z*, because it will not have any
1286 // effect on the final result. (We'd be adding a bunch of
1287 // zeros to the end of zm that would just be removed in
1288 // normalize.) However, if that is the case, then Stage 3 is
1289 // even more important for accuracy.
1290 if (correction != 0)
1291 {
1292 zm *= correctionFactor;
1293 // divide by the correctionFactor by moving the exponent, so we don't lose the
1294 // integer value we just computed
1295 ze -= correctionExponent;
1296
1297 zm += correction;
1298 }
1299
1300 // Stage 3: If there's still anything left, and the cusp
1301 // rounding fix is enabled, flag if there is still
1302 // a remainder from stage 2.
1303 bool const useTrailingRemainder =
1305 if (useTrailingRemainder)
1306 {
1307 dropped = partialNumerator % dm != 0;
1308 }
1309 }
1310 }
1311 doNormalize(zp, zm, ze, minMantissa, maxMantissa, cuspRoundingFix, dropped);
1312 negative_ = zp;
1313 mantissa_ = static_cast<internalrep>(zm);
1314 exponent_ = ze;
1315 XRPL_ASSERT_PARTS(isnormal(), "xrpl::Number::operator/=", "result is normalized");
1316
1317 return *this;
1318}
1319
1320Number::
1321operator rep() const
1322{
1323 rep drops = mantissa();
1324 int offset = exponent();
1325 Guard g(kRange);
1326 if (drops != 0)
1327 {
1328 if (negative_)
1329 {
1330 g.setNegative();
1331 drops = -drops;
1332 }
1333 while (offset < 0)
1334 {
1335 g.doDropDigit(drops, offset);
1336 }
1337 for (; offset > 0; --offset)
1338 {
1339 if (drops > kMaxRep / 10)
1340 throw std::overflow_error("Number::operator rep() overflow");
1341 drops *= 10;
1342 }
1343 g.doRound(drops, "Number::operator rep() rounding overflow");
1344 }
1345 return drops;
1346}
1347
1348Number
1349Number::truncate() const noexcept
1350{
1351 if (exponent_ >= 0 || mantissa_ == 0)
1352 return *this;
1353
1354 Number ret = *this;
1355 while (ret.exponent_ < 0 && ret.mantissa_ != 0)
1356 {
1357 ret.exponent_ += 1;
1358 ret.mantissa_ /= rep(10);
1359 }
1360 // We are guaranteed that normalize() will never throw an exception
1361 // because exponent is either negative or zero at this point.
1362 ret.normalize(kRange);
1363 return ret;
1364}
1365
1367to_string(Number const& amount)
1368{
1369 // keep full internal accuracy, but make more human friendly if possible
1370 static constexpr Number kZero = Number{};
1371 if (amount == kZero)
1372 return "0";
1373
1374 auto exponent = amount.exponent_;
1375 auto mantissa = amount.mantissa_;
1376 bool const negative = amount.negative_;
1377
1378 // Use scientific notation for exponents that are too small or too large
1379 auto const rangeLog = Number::mantissaLog();
1380 if (((exponent != 0) && ((exponent < -(rangeLog + 10)) || (exponent > -(rangeLog - 10)))))
1381 {
1382 while (mantissa != 0 && mantissa % 10 == 0 && exponent < Number::kMaxExponent)
1383 {
1384 mantissa /= 10;
1385 ++exponent;
1386 }
1387 std::string ret = negative ? "-" : "";
1389 if (exponent != 0)
1390 {
1391 ret.append(1, 'e');
1393 }
1394 return ret;
1395 }
1396
1397 XRPL_ASSERT(exponent + 43 > 0, "xrpl::to_string(Number) : minimum exponent");
1398
1399 ptrdiff_t const padPrefix = rangeLog + 12;
1400 ptrdiff_t const padSuffix = rangeLog + 8;
1401
1402 std::string const rawValue(std::to_string(mantissa));
1403 std::string val;
1404
1405 val.reserve(rawValue.length() + padPrefix + padSuffix);
1406 val.append(padPrefix, '0');
1407 val.append(rawValue);
1408 val.append(padSuffix, '0');
1409
1410 ptrdiff_t const offset(exponent + padPrefix + rangeLog + 1);
1411
1412 auto preFrom(val.begin());
1413 auto const preTo(val.begin() + offset);
1414
1415 auto const postFrom(val.begin() + offset);
1416 auto postTo(val.end());
1417
1418 // Crop leading zeroes. Take advantage of the fact that there's always a
1419 // fixed amount of leading zeroes and skip them.
1420 if (std::distance(preFrom, preTo) > padPrefix)
1421 preFrom += padPrefix;
1422
1423 XRPL_ASSERT(postTo >= postFrom, "xrpl::to_string(Number) : first distance check");
1424
1425 preFrom = std::find_if(preFrom, preTo, [](char c) { return c != '0'; });
1426
1427 // Crop trailing zeroes. Take advantage of the fact that there's always a
1428 // fixed amount of trailing zeroes and skip them.
1429 if (std::distance(postFrom, postTo) > padSuffix)
1430 postTo -= padSuffix;
1431
1432 XRPL_ASSERT(postTo >= postFrom, "xrpl::to_string(Number) : second distance check");
1433
1434 postTo = std::find_if(
1437 [](char c) { return c != '0'; })
1438 .base();
1439
1440 std::string ret;
1441
1442 if (negative)
1443 ret.append(1, '-');
1444
1445 // Assemble the output:
1446 if (preFrom == preTo)
1447 {
1448 ret.append(1, '0');
1449 }
1450 else
1451 {
1452 ret.append(preFrom, preTo);
1453 }
1454
1455 if (postTo != postFrom)
1456 {
1457 ret.append(1, '.');
1458 ret.append(postFrom, postTo);
1459 }
1460
1461 return ret;
1462}
1463
1464// Returns f^n
1465// Uses a log_2(n) number of multiplications
1466
1467Number
1468power(Number const& f, unsigned n)
1469{
1470 if (n == 0)
1471 return Number::one();
1472 if (n == 1)
1473 return f;
1474 auto r = power(f, n / 2);
1475 r *= r;
1476 if (n % 2 != 0)
1477 r *= f;
1478 return r;
1479}
1480
1481// Returns f^(1/d)
1482// Uses Newton–Raphson iterations until the result stops changing
1483// to find the non-negative root of the polynomial g(x) = x^d - f
1484
1485// This function, and power(Number f, unsigned n, unsigned d)
1486// treat corner cases such as 0 roots as advised by Annex F of
1487// the C standard, which itself is consistent with the IEEE
1488// floating point standards.
1489
1490Number
1491root(Number f, unsigned d)
1492{
1493 static constexpr Number kZero = Number{};
1494 auto const one = Number::one();
1495
1496 if (f == one || d == 1)
1497 return f;
1498 if (d == 0)
1499 {
1500 if (f == -one)
1501 return one;
1502 if (abs(f) < one)
1503 return kZero;
1504 throw std::overflow_error("Number::root infinity");
1505 }
1506 if (f < kZero && d % 2 == 0)
1507 throw std::overflow_error("Number::root nan");
1508 if (f == kZero)
1509 return f;
1510
1511 // Scale f into the range (0, 1) such that f's exponent is a multiple of d
1512 auto e = f.exponent_ + Number::mantissaLog() + 1;
1513 auto const di = static_cast<int>(d);
1514 auto ex = [e = e, di = di]() // Euclidean remainder of e/d
1515 {
1516 int const k = (e >= 0 ? e : e - (di - 1)) / di;
1517 int const k2 = e - (k * di);
1518 if (k2 == 0)
1519 return 0;
1520 return di - k2;
1521 }();
1522 e += ex;
1523 f = f.shiftExponent(-e); // f /= 10^e;
1524
1525 XRPL_ASSERT_PARTS(f.isnormal(), "xrpl::root(Number, unsigned)", "f is normalized");
1526 bool neg = false;
1527 if (f < kZero)
1528 {
1529 neg = true;
1530 f = -f;
1531 }
1532
1533 // Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
1534
1535 // NOLINTNEXTLINE(readability-identifier-naming)
1536 auto const D = (((((6 * di) + 11) * di) + 6) * di) + 1;
1537 auto const a0 = 3 * di * ((((2 * di) - 3) * di) + 1);
1538 auto const a1 = 24 * di * ((2 * di) - 1);
1539 auto const a2 = -30 * (di - 1) * di;
1540 Number r = ((Number{a2} * f + Number{a1}) * f + Number{a0}) / Number{D};
1541 if (neg)
1542 {
1543 f = -f;
1544 r = -r;
1545 }
1546
1547 // Newton–Raphson iteration of f^(1/d) with initial guess r
1548 // halt when r stops changing, checking for bouncing on the last iteration
1549 Number rm1{};
1550 Number rm2{};
1551 do
1552 {
1553 rm2 = rm1;
1554 rm1 = r;
1555 r = (Number(d - 1) * r + f / power(r, d - 1)) / Number(d);
1556 } while (r != rm1 && r != rm2);
1557
1558 // return r * 10^(e/d) to reverse scaling
1559 auto const result = r.shiftExponent(e / di);
1560 XRPL_ASSERT_PARTS(result.isnormal(), "xrpl::root(Number, unsigned)", "result is normalized");
1561 return result;
1562}
1563
1564Number
1566{
1567 static constexpr Number kZero = Number{};
1568 auto const one = Number::one();
1569
1570 if (f == one)
1571 return f;
1572 if (f < kZero)
1573 throw std::overflow_error("Number::root nan");
1574 if (f == kZero)
1575 return f;
1576
1577 // Scale f into the range (0, 1) such that f's exponent is a multiple of d
1578 auto e = f.exponent_ + Number::mantissaLog() + 1;
1579 if (e % 2 != 0)
1580 ++e;
1581 f = f.shiftExponent(-e); // f /= 10^e;
1582 XRPL_ASSERT_PARTS(f.isnormal(), "xrpl::root2(Number)", "f is normalized");
1583
1584 // Quadratic least squares curve fit of f^(1/d) in the range [0, 1]
1585 auto const D = 105; // NOLINT(readability-identifier-naming)
1586 auto const a0 = 18;
1587 auto const a1 = 144;
1588 auto const a2 = -60;
1589 Number r = ((Number{a2} * f + Number{a1}) * f + Number{a0}) / Number{D};
1590
1591 // Newton–Raphson iteration of f^(1/2) with initial guess r
1592 // halt when r stops changing, checking for bouncing on the last iteration
1593 Number rm1{};
1594 Number rm2{};
1595 do
1596 {
1597 rm2 = rm1;
1598 rm1 = r;
1599 r = (r + f / r) / Number(2);
1600 } while (r != rm1 && r != rm2);
1601
1602 // return r * 10^(e/2) to reverse scaling
1603 auto const result = r.shiftExponent(e / 2);
1604 XRPL_ASSERT_PARTS(result.isnormal(), "xrpl::root2(Number)", "result is normalized");
1605
1606 return result;
1607}
1608
1609// Returns f^(n/d)
1610
1611Number
1612power(Number const& f, unsigned n, unsigned d)
1613{
1614 static constexpr Number kZero = Number{};
1615 auto const one = Number::one();
1616
1617 if (f == one)
1618 return f;
1619 auto g = std::gcd(n, d);
1620 if (g == 0)
1621 throw std::overflow_error("Number::power nan");
1622 if (d == 0)
1623 {
1624 if (f == -one)
1625 return one;
1626 if (abs(f) < one)
1627 return kZero;
1628 // abs(f) > one
1629 throw std::overflow_error("Number::power infinity");
1630 }
1631 if (n == 0)
1632 return one;
1633 n /= g;
1634 d /= g;
1635 if ((n % 2) == 1 && (d % 2) == 0 && f < kZero)
1636 throw std::overflow_error("Number::power nan");
1637 return root(power(f, n), d);
1638}
1639
1640} // namespace xrpl
T append(T... args)
T begin(T... args)
static constexpr MantissaRange const & mantissaRange(MantissaScale scale)
bool empty() const noexcept
Guard(internalrep const &minMantissa, internalrep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFix)
bool isNegative() const noexcept
Guard(MantissaRange const &range)
void doDropDigit(T &mantissa, int &exponent) noexcept
Drop a digit from the mantissa, and increment the exponent, storing the dropped digit in this Guard.
MantissaRange::CuspRoundingFix const cuspRoundingFix
void doRoundUp(bool &negative, T &mantissa, int &exponent, std::string location)
void doPush(unsigned d) noexcept
void doRoundDown(bool &negative, T &mantissa, int &exponent) const
void bringIntoRange(bool &negative, T &mantissa, int &exponent) const
Round round() const noexcept
void doRound(rep &drops, std::string location) const
Number is a floating point type that can represent a wide range of values.
Definition Number.h:351
internalrep mantissa_
Definition Number.h:356
static internalrep minMantissa()
Definition Number.h:562
constexpr rep mantissa() const noexcept
Returns the mantissa of the external view of the Number.
Definition Number.h:692
Number & operator/=(Number const &x)
Number & operator+=(Number const &x)
static constexpr internalrep kMaxRepUp
Definition Number.h:367
Number truncate() const noexcept
std::int64_t rep
Definition Number.h:352
friend std::string to_string(Number const &amount)
static constexpr int kMinExponent
Definition Number.h:361
static RoundingMode setround(RoundingMode inMode)
static RoundingMode mode
Definition Number.h:598
friend void doNormalize(bool &negative, T &mantissa, int &exponent, MantissaRange::rep const &minMantissa, MantissaRange::rep const &maxMantissa, MantissaRange::CuspRoundingFix cuspRoundingFix, bool dropped)
MantissaRange::rep internalrep
Definition Number.h:353
static Number max() noexcept
Definition Number.h:819
static RoundingMode getround()
static std::reference_wrapper< MantissaRange const > kRange
Definition Number.h:604
static constexpr internalrep kMaxRep
Definition Number.h:364
Number shiftExponent(int exponentDelta) const
static MantissaRange::MantissaScale getMantissaScale()
Returns which mantissa scale is currently in use for normalization.
static internalrep externalToInternal(rep mantissa)
static internalrep maxMantissa()
Definition Number.h:568
static constexpr int kMaxExponent
Definition Number.h:362
bool isnormal() const noexcept
Definition Number.h:831
constexpr int exponent() const noexcept
Returns the exponent of the external view of the Number.
Definition Number.h:714
friend Number root2(Number f)
static Number min() noexcept
Definition Number.h:813
int exponent_
Definition Number.h:357
void normalize(MantissaRange const &range)
Number & operator*=(Number const &x)
constexpr Number()=default
static void setMantissaScale(MantissaRange::MantissaScale scale)
Changes which mantissa scale is used for normalization.
bool negative_
Definition Number.h:355
static int mantissaLog()
Definition Number.h:574
friend Number root(Number f, unsigned d)
T distance(T... args)
T end(T... args)
T exchange(T... args)
T find_if(T... args)
T gcd(T... args)
T is_same_v
T is_unsigned_v
T make_reverse_iterator(T... args)
T max(T... args)
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:37
int scale(Number const &number, Asset const &asset)
Get the scale of a Number for a given asset.
Definition STAmount.h:794
Number root(Number f, unsigned d)
Number power(Number const &f, unsigned n)
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
constexpr auto kPowerOfTen
Definition Number.h:88
constexpr bool isPowerOfTen(T value)
Definition Number.h:43
constexpr Number abs(Number x) noexcept
Definition Number.h:876
static unsigned divu10(uint128_t &u)
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T reserve(T... args)
T length(T... args)
MantissaRange defines a range for the mantissa of a normalized Number.
Definition Number.h:131
rep const min
Definition Number.h:173
MantissaScale const scale
Definition Number.h:171
std::uint64_t rep
Definition Number.h:132
int const log
Definition Number.h:172
CuspRoundingFix const cuspRoundingFix
Definition Number.h:175
constexpr MantissaRange(MantissaScale sc)
Definition Number.h:167
static std::set< MantissaScale > const & getAllScales()
Definition Number.h:178
rep const max
Definition Number.h:174
T to_string(T... args)