From 382adcc93c54792507018a21aedda6e58a22f8f8 Mon Sep 17 00:00:00 2001 From: Edward Hennis Date: Fri, 10 Jul 2015 17:47:47 -0400 Subject: [PATCH] Move mulDiv and lowestTerms to STAmount.cpp --- src/ripple/core/impl/LoadFeeTrack.cpp | 35 --------------------------- src/ripple/protocol/STAmount.h | 21 ++++++++++++++++ src/ripple/protocol/impl/STAmount.cpp | 20 +++++++++++++++ 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/src/ripple/core/impl/LoadFeeTrack.cpp b/src/ripple/core/impl/LoadFeeTrack.cpp index 3131f551ae..7235e6fe5b 100644 --- a/src/ripple/core/impl/LoadFeeTrack.cpp +++ b/src/ripple/core/impl/LoadFeeTrack.cpp @@ -25,41 +25,6 @@ namespace ripple { -template -void lowestTerms(T1& a, T2& b) -{ - std::uint64_t x = a, y = b; - while (y != 0) - { - auto t = x % y; - x = y; - y = t; - } - a /= x; - b /= x; -} - -// TODO REMOVE! -static -std::uint64_t -mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div) -{ - lowestTerms(value, div); - lowestTerms(mul, div); - - if (value < mul) - std::swap(value, mul); - const auto max = std::numeric_limits::max(); - if (value > max / mul) - { - value /= div; - if (value > max / mul) - throw std::overflow_error("mulDiv"); - return value * mul; - } - return value * mul / div; -} - // Scale from fee units to millionths of a ripple std::uint64_t LoadFeeTrack::scaleFeeBase (std::uint64_t fee, std::uint64_t baseFee, diff --git a/src/ripple/protocol/STAmount.h b/src/ripple/protocol/STAmount.h index adb2249c71..27a3921d1e 100644 --- a/src/ripple/protocol/STAmount.h +++ b/src/ripple/protocol/STAmount.h @@ -400,6 +400,27 @@ inline bool isXRP(STAmount const& amount) return isXRP (amount.issue().currency); } +/** + A utility function to compute (value)*(mul)/(div) while avoiding + overflow but keeping precision. +*/ +std::uint64_t +mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div); + +template +void lowestTerms(T1& a, T2& b) +{ + std::uint64_t x = a, y = b; + while (y != 0) + { + auto t = x % y; + x = y; + y = t; + } + a /= x; + b /= x; +} + } // ripple #endif diff --git a/src/ripple/protocol/impl/STAmount.cpp b/src/ripple/protocol/impl/STAmount.cpp index 3ecc9abe8b..d818923219 100644 --- a/src/ripple/protocol/impl/STAmount.cpp +++ b/src/ripple/protocol/impl/STAmount.cpp @@ -1257,4 +1257,24 @@ divRound (STAmount const& num, STAmount const& den, return STAmount (issue, amount, offset, resultNegative); } +// compute (value)*(mul)/(div) - avoid overflow but keep precision +std::uint64_t +mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div) +{ + lowestTerms(value, div); + lowestTerms(mul, div); + + if (value < mul) + std::swap(value, mul); + const auto max = std::numeric_limits::max(); + if (value > max / mul) + { + value /= div; + if (value > max / mul) + throw std::overflow_error("mulDiv"); + return value * mul; + } + return value * mul / div; +} + } // ripple