Google OR-Tools: ortools/base/mathutil.h Source File
38 template <typename IntegralType>
39 static IntegralType CeilOfRatio(IntegralType numerator,
40 IntegralType denominator) {
42 const IntegralType rounded_toward_zero = numerator / denominator;
43 const IntegralType intermediate_product = rounded_toward_zero * denominator;
44 const bool needs_adjustment =
45 (rounded_toward_zero >= 0) &&
46 ((denominator > 0 && numerator > intermediate_product) ||
47 (denominator < 0 && numerator < intermediate_product));
48 const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);
49 const IntegralType ceil_of_ratio = rounded_toward_zero + adjustment;
52 template <typename IntegralType>
53 static IntegralType FloorOfRatio(IntegralType numerator,
54 IntegralType denominator) {
56 const IntegralType rounded_toward_zero = numerator / denominator;
57 const IntegralType intermediate_product = rounded_toward_zero * denominator;
58 const bool needs_adjustment =
59 (rounded_toward_zero <= 0) &&
60 ((denominator > 0 && numerator < intermediate_product) ||
61 (denominator < 0 && numerator > intermediate_product));
62 const IntegralType adjustment = static_cast<IntegralType>(needs_adjustment);
63 const IntegralType floor_of_ratio = rounded_toward_zero - adjustment;
120 return pow(base, exp);
123 template <class IntOut, class FloatIn>
124 static IntOut Round(FloatIn x) {
129 if (x > -0.5 && x < 0.5) {
133 return static_cast<IntOut>(0);
135 return static_cast<IntOut>(x < 0 ? (x - 0.5) : (x + 0.5));
142 template <typename IntType>
143 static IntType RoundUpTo(IntType input_value, IntType rounding_value) {
144 static_assert(std::numeric_limits<IntType>::is_integer,
145 "RoundUpTo() operation type is not integer");
146 DCHECK_GE(input_value, 0);
147 DCHECK_GT(rounding_value, 0);
148 const IntType remainder = input_value % rounding_value;
149 return (remainder == 0) ? input_value
173 template <class IntOut, class FloatIn>
181 if (!std::numeric_limits<IntOut>::is_signed && x < 0) {
187 return x < 0 ? std::numeric_limits<IntOut>::lowest()
188 : std::numeric_limits<IntOut>::max();
202 if (exp <= std::numeric_limits<IntOut>::digits) {
207 return x < 0 ? std::numeric_limits<IntOut>::lowest()
224 template <class IntOut, class FloatIn>
225 static IntOut SafeRound(FloatIn x) {
261 static double Stirling(double n);
311 static bool AlmostEquals(const T x, const T y) {
312 static_assert(std::is_arithmetic_v<T>);
313 if constexpr (std::numeric_limits<T>::is_integer) {
314 return x == y;
319 if (std::abs(x) <= 1e-6 && std::abs(y) <= 1e-6) return true;
320 if (std::abs(x - y) <= 1e-6) return true;
321 return std::abs(x - y) / std::max(std::abs(x), std::abs(y)) <= 1e-6;